mut_fcntl.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:4k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1996-2002
  5.  * Sleepycat Software.  All rights reserved.
  6.  */
  7. #include "db_config.h"
  8. #ifndef lint
  9. static const char revid[] = "$Id: mut_fcntl.c,v 11.21 2002/05/31 19:37:45 bostic Exp $";
  10. #endif /* not lint */
  11. #ifndef NO_SYSTEM_INCLUDES
  12. #include <sys/types.h>
  13. #include <fcntl.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <unistd.h>
  17. #endif
  18. #include "db_int.h"
  19. /*
  20.  * __db_fcntl_mutex_init --
  21.  * Initialize a DB mutex structure.
  22.  *
  23.  * PUBLIC: int __db_fcntl_mutex_init __P((DB_ENV *, DB_MUTEX *, u_int32_t));
  24.  */
  25. int
  26. __db_fcntl_mutex_init(dbenv, mutexp, offset)
  27. DB_ENV *dbenv;
  28. DB_MUTEX *mutexp;
  29. u_int32_t offset;
  30. {
  31. u_int32_t save;
  32. /*
  33.  * The only setting/checking of the MUTEX_MPOOL flags is in the mutex
  34.  * mutex allocation code (__db_mutex_alloc/free).  Preserve only that
  35.  * flag.  This is safe because even if this flag was never explicitly
  36.  * set, but happened to be set in memory, it will never be checked or
  37.  * acted upon.
  38.  */
  39. save = F_ISSET(mutexp, MUTEX_MPOOL);
  40. memset(mutexp, 0, sizeof(*mutexp));
  41. F_SET(mutexp, save);
  42. /*
  43.  * This is where we decide to ignore locks we don't need to set -- if
  44.  * the application is private, we don't need any locks.
  45.  */
  46. if (F_ISSET(dbenv, DB_ENV_PRIVATE)) {
  47. F_SET(mutexp, MUTEX_IGNORE);
  48. return (0);
  49. }
  50. mutexp->off = offset;
  51. #ifdef HAVE_MUTEX_SYSTEM_RESOURCES
  52. mutexp->reg_off = INVALID_ROFF;
  53. #endif
  54. F_SET(mutexp, MUTEX_INITED);
  55. return (0);
  56. }
  57. /*
  58.  * __db_fcntl_mutex_lock
  59.  * Lock on a mutex, blocking if necessary.
  60.  *
  61.  * PUBLIC: int __db_fcntl_mutex_lock __P((DB_ENV *, DB_MUTEX *));
  62.  */
  63. int
  64. __db_fcntl_mutex_lock(dbenv, mutexp)
  65. DB_ENV *dbenv;
  66. DB_MUTEX *mutexp;
  67. {
  68. struct flock k_lock;
  69. int locked, ms, waited;
  70. if (F_ISSET(dbenv, DB_ENV_NOLOCKING))
  71. return (0);
  72. /* Initialize the lock. */
  73. k_lock.l_whence = SEEK_SET;
  74. k_lock.l_start = mutexp->off;
  75. k_lock.l_len = 1;
  76. for (locked = waited = 0;;) {
  77. /*
  78.  * Wait for the lock to become available; wait 1ms initially,
  79.  * up to 1 second.
  80.  */
  81. for (ms = 1; mutexp->pid != 0;) {
  82. waited = 1;
  83. __os_yield(NULL, ms * USEC_PER_MS);
  84. if ((ms <<= 1) > MS_PER_SEC)
  85. ms = MS_PER_SEC;
  86. }
  87. /* Acquire an exclusive kernel lock. */
  88. k_lock.l_type = F_WRLCK;
  89. if (fcntl(dbenv->lockfhp->fd, F_SETLKW, &k_lock))
  90. return (__os_get_errno());
  91. /* If the resource is still available, it's ours. */
  92. if (mutexp->pid == 0) {
  93. locked = 1;
  94. __os_id(&mutexp->pid);
  95. }
  96. /* Release the kernel lock. */
  97. k_lock.l_type = F_UNLCK;
  98. if (fcntl(dbenv->lockfhp->fd, F_SETLK, &k_lock))
  99. return (__os_get_errno());
  100. /*
  101.  * If we got the resource lock we're done.
  102.  *
  103.  * !!!
  104.  * We can't check to see if the lock is ours, because we may
  105.  * be trying to block ourselves in the lock manager, and so
  106.  * the holder of the lock that's preventing us from getting
  107.  * the lock may be us!  (Seriously.)
  108.  */
  109. if (locked)
  110. break;
  111. }
  112. if (waited)
  113. ++mutexp->mutex_set_wait;
  114. else
  115. ++mutexp->mutex_set_nowait;
  116. return (0);
  117. }
  118. /*
  119.  * __db_fcntl_mutex_unlock --
  120.  * Release a lock.
  121.  *
  122.  * PUBLIC: int __db_fcntl_mutex_unlock __P((DB_ENV *, DB_MUTEX *));
  123.  */
  124. int
  125. __db_fcntl_mutex_unlock(dbenv, mutexp)
  126. DB_ENV *dbenv;
  127. DB_MUTEX *mutexp;
  128. {
  129. if (F_ISSET(dbenv, DB_ENV_NOLOCKING))
  130. return (0);
  131. #ifdef DIAGNOSTIC
  132. #define MSG "mutex_unlock: ERROR: released lock that was unlockedn"
  133. #ifndef STDERR_FILENO
  134. #define STDERR_FILENO 2
  135. #endif
  136. if (mutexp->pid == 0)
  137. write(STDERR_FILENO, MSG, sizeof(MSG) - 1);
  138. #endif
  139. /*
  140.  * Release the resource.  We don't have to acquire any locks because
  141.  * processes trying to acquire the lock are checking for a pid set to
  142.  * 0/non-0, not to any specific value.
  143.  */
  144. mutexp->pid = 0;
  145. return (0);
  146. }
  147. /*
  148.  * __db_fcntl_mutex_destroy --
  149.  * Destroy a DB_MUTEX.
  150.  *
  151.  * PUBLIC: int __db_fcntl_mutex_destroy __P((DB_MUTEX *));
  152.  */
  153. int
  154. __db_fcntl_mutex_destroy(mutexp)
  155. DB_MUTEX *mutexp;
  156. {
  157. COMPQUIET(mutexp, NULL);
  158. return (0);
  159. }