⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 semaphore.c

📁 GNUnet是一个安全的点对点网络框架
💻 C
📖 第 1 页 / 共 2 页
字号:
        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 + -