📄 semaphore.c
字号:
GNUNET_GE_DIE_STRERROR (ectx, GNUNET_GE_FATAL | GNUNET_GE_USER | GNUNET_GE_IMMEDIATE, "semtcl"); } if (semop (ret->internal, &op_endcreate[0], 2) < 0) GNUNET_GE_DIE_STRERROR (ectx, GNUNET_GE_FATAL | GNUNET_GE_USER | GNUNET_GE_IMMEDIATE, "semop"); ret->filename = ebasename; return ret;#elif SOMEBSD int fd; int cnt; struct GNUNET_IPC_Semaphore *ret; ret = GNUNET_malloc (sizeof (struct GNUNET_IPC_Semaphore)); ret->ectx = ectx; ret->internalLock = GNUNET_mutex_create (GNUNET_NO); ret->filename = GNUNET_strdup (basename); fd = -1; while (fd == -1) { fd = GNUNET_disk_file_open (ectx, basename, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP /* 660 */ ); if ((fd == -1) && (errno == EEXIST)) { /* try without creation */ fd = GNUNET_disk_file_open (ectx, basename, O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP /* 660 */ ); /* possibly the file was deleted in the meantime, then try again with O_CREAT! */ if ((fd == -1) && (errno != ENOENT)) break; } } if (fd == -1) { GNUNET_GE_LOG_STRERROR_FILE (ectx, GNUNET_GE_ERROR | GNUNET_GE_USER | GNUNET_GE_BULK, "open", ret->filename); GNUNET_mutex_destroy (ret->internalLock); GNUNET_free (ret->filename); GNUNET_free (ret); return NULL; } FLOCK (fd, LOCK_EX); if (sizeof (int) != READ (fd, &cnt, sizeof (int))) { cnt = htonl (initialValue); SEMA_LSEEK (fd, 0, SEEK_SET); if (sizeof (int) != WRITE (fd, &cnt, sizeof (int))) GNUNET_GE_LOG_STRERROR_FILE (ectx, GNUNET_GE_ERROR | GNUNET_GE_USER | GNUNET_GE_BULK, "write", basename); } SEMA_LSEEK (fd, sizeof (int), SEEK_SET); if (sizeof (int) != READ (fd, &cnt, sizeof (int))) cnt = htonl (1); else cnt = htonl (ntohl (cnt) + 1); SEMA_LSEEK (fd, sizeof (int), SEEK_SET); if (sizeof (int) != WRITE (fd, &cnt, sizeof (int))) GNUNET_GE_LOG_STRERROR_FILE (ectx, GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK, "write", basename); FLOCK (fd, LOCK_UN); ret->fd = fd; ret->initialValue = initialValue; return ret;#else#ifndef _MSC_VER#warning Port IPC. return NULL;#else return NULL;#endif#endif}voidGNUNET_IPC_semaphore_up (struct GNUNET_IPC_Semaphore *sem){ if (sem == NULL) /* error on creation, optimistic execution; good luck */ return;#if SOLARIS || OSX || GNUNET_freeBSD5 if (0 != sem_post (sem->internal)) GNUNET_GE_LOG_STRERROR (sem->ectx, GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK, "sem_post");#elif WINDOWS if (!ReleaseSemaphore (sem->internal, 1, NULL)) GNUNET_GE_LOG (sem->ectx, GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK, "ReleaseSemaphore signaled error: %i\n", GetLastError ());#elif LINUX { struct sembuf sops = { 0, 1, SEM_UNDO }; if (0 != semop (sem->internal, &sops, 1)) GNUNET_GE_LOG_STRERROR (sem->ectx, GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK, "semop"); }#elif SOMEBSD { int cnt; GNUNET_mutex_lock (sem->internalLock); FLOCK (sem->fd, LOCK_EX); SEMA_LSEEK (sem->fd, 0, SEEK_SET); if (sizeof (int) != READ (sem->fd, &cnt, sizeof (int))) { GNUNET_GE_LOG_STRERROR_FILE (sem->ectx, GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK, "read", sem->filename); FLOCK (sem->fd, LOCK_UN); GNUNET_mutex_unlock (sem->internalLock); return; } cnt = htonl (ntohl (cnt) + 1); SEMA_LSEEK (sem->fd, 0, SEEK_SET); if (sizeof (int) != WRITE (sem->fd, &cnt, sizeof (int))) GNUNET_GE_LOG_STRERROR_FILE (sem->ectx, GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK, "write", sem->filename); FLOCK (sem->fd, LOCK_UN); GNUNET_mutex_unlock (sem->internalLock); }#endif}/* FIXME: add support for mayBlock! */intGNUNET_IPC_semaphore_down (struct GNUNET_IPC_Semaphore *sem, int mayBlock){ if (sem == NULL) /* error on creation, optimistic execution; good luck */ return GNUNET_OK;#if OSX || SOLARIS || GNUNET_freeBSD5 while (0 != sem_wait (sem->internal)) { if ((errno == EINTR) || (errno == EAGAIN)) continue; GNUNET_GE_DIE_STRERROR (sem->ectx, GNUNET_GE_FATAL | GNUNET_GE_USER | GNUNET_GE_IMMEDIATE, "sem_wait"); } return GNUNET_OK;#elif WINDOWS if (WaitForSingleObject (sem->internal, INFINITE) == WAIT_FAILED) GNUNET_GE_LOG_STRERROR (sem->ectx, GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK, "WaitForSingleObject"); return GNUNET_OK;#elif LINUX { struct sembuf sops = { 0, -1, SEM_UNDO }; while (0 != semop (sem->internal, &sops, 1)) { if ((errno == EINTR) || (errno == EAGAIN)) continue; GNUNET_GE_DIE_STRERROR (sem->ectx, GNUNET_GE_FATAL | GNUNET_GE_USER | GNUNET_GE_IMMEDIATE, "semop"); } return GNUNET_OK; }#elif SOMEBSD { int cnt; GNUNET_mutex_lock (sem->internalLock); FLOCK (sem->fd, LOCK_EX); cnt = ntohl (0); while (htonl (cnt) == 0) { SEMA_LSEEK (sem->fd, 0, SEEK_SET); if (sizeof (int) != READ (sem->fd, &cnt, sizeof (int))) { GNUNET_GE_LOG_STRERROR_FILE (sem->ectx, GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK, "read", sem->filename); FLOCK (sem->fd, LOCK_UN); GNUNET_mutex_unlock (sem->internalLock); return GNUNET_SYSERR; } if (htonl (cnt) == 0) { /* busy wait! */ FLOCK (sem->fd, LOCK_UN); GNUNET_thread_sleep (50 * GNUNET_CRON_MILLISECONDS); FLOCK (sem->fd, LOCK_EX); } } cnt = htonl (ntohl (cnt) - 1); SEMA_LSEEK (sem->fd, 0, SEEK_SET); if (sizeof (int) != WRITE (sem->fd, &cnt, sizeof (int))) GNUNET_GE_LOG_STRERROR_FILE (sem->ectx, GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK, "write", sem->filename); FLOCK (sem->fd, LOCK_UN); GNUNET_mutex_unlock (sem->internalLock); } return GNUNET_OK;#else return GNUNET_OK;#endif}voidGNUNET_IPC_semaphore_destroy (struct GNUNET_IPC_Semaphore *sem){ if (sem == NULL) /* error on creation, optimistic execution; good luck */ return;#if SOLARIS || OSX || GNUNET_freeBSD5 if (0 != sem_close (sem->internal)) GNUNET_GE_LOG_STRERROR (sem->ectx, GNUNET_GE_USER | GNUNET_GE_WARNING | GNUNET_GE_BULK, "sem_close");#elif WINDOWS if (!CloseHandle (sem->internal)) GNUNET_GE_LOG (sem->ectx, GNUNET_GE_USER | GNUNET_GE_WARNING | GNUNET_GE_BULK, "CloseHandle signaled error: %i\n", GetLastError ());#elif LINUX { int pcount; if (semop (sem->internal, &op_close[0], 3) < 0) GNUNET_GE_LOG_STRERROR (sem->ectx, GNUNET_GE_USER | GNUNET_GE_WARNING | GNUNET_GE_BULK, "semop"); if ((pcount = semctl (sem->internal, 1, GETVAL, 0)) < 0) GNUNET_GE_LOG_STRERROR (sem->ectx, GNUNET_GE_USER | GNUNET_GE_WARNING | GNUNET_GE_BULK, "semctl"); if (pcount > PROCCOUNT) { GNUNET_GE_BREAK (sem->ectx, 0); } else if (pcount == PROCCOUNT) { if (0 != semctl (sem->internal, 0, IPC_RMID, 0)) GNUNET_GE_LOG_STRERROR (sem->ectx, GNUNET_GE_USER | GNUNET_GE_WARNING | GNUNET_GE_BULK, "semctl"); UNLINK (sem->filename); } else { if (semop (sem->internal, &op_unlock[0], 1) < 0) GNUNET_GE_LOG_STRERROR (sem->ectx, GNUNET_GE_USER | GNUNET_GE_WARNING | GNUNET_GE_BULK, "semop"); } GNUNET_free (sem->filename); }#elif SOMEBSD { int cnt; GNUNET_mutex_destroy (sem->internalLock); FLOCK (sem->fd, LOCK_EX); SEMA_LSEEK (sem->fd, sizeof (int), SEEK_SET); if (sizeof (int) == READ (sem->fd, &cnt, sizeof (int))) { cnt = htonl (ntohl (cnt) - 1); SEMA_LSEEK (sem->fd, sizeof (int), SEEK_SET); if (sizeof (int) != WRITE (sem->fd, &cnt, sizeof (int))) GNUNET_GE_LOG_STRERROR (sem->ectx, GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK, "write"); if (ntohl (cnt) == 0) UNLINK (sem->filename); } else GNUNET_GE_LOG_STRERROR (sem->ectx, GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK, "read"); FLOCK (sem->fd, LOCK_UN); GNUNET_disk_file_close (sem->ectx, sem->filename, sem->fd); GNUNET_free (sem->filename); }#else#endif GNUNET_free (sem);}/* end of semaphore.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -