mut_fcntl.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:3k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1996, 1997, 1998, 1999, 2000
  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.11 2001/01/11 18:19:53 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 *, MUTEX *, u_int32_t));
  24.  */
  25. int
  26. __db_fcntl_mutex_init(dbenv, mutexp, offset)
  27. DB_ENV *dbenv;
  28. MUTEX *mutexp;
  29. u_int32_t offset;
  30. {
  31. memset(mutexp, 0, sizeof(*mutexp));
  32. /*
  33.  * This is where we decide to ignore locks we don't need to set -- if
  34.  * the application is private, we don't need any locks.
  35.  */
  36. if (F_ISSET(dbenv, DB_ENV_PRIVATE)) {
  37. F_SET(mutexp, MUTEX_IGNORE);
  38. return (0);
  39. }
  40. mutexp->off = offset;
  41. #ifdef MUTEX_SYSTEM_RESOURCES
  42. mutexp->reg_off = INVALID_ROFF;
  43. #endif
  44. F_SET(mutexp, MUTEX_INITED);
  45. return (0);
  46. }
  47. /*
  48.  * __db_fcntl_mutex_lock
  49.  * Lock on a mutex, blocking if necessary.
  50.  *
  51.  * PUBLIC: int __db_fcntl_mutex_lock __P((DB_ENV *, MUTEX *, DB_FH *));
  52.  */
  53. int
  54. __db_fcntl_mutex_lock(dbenv, mutexp, fhp)
  55. DB_ENV *dbenv;
  56. MUTEX *mutexp;
  57. DB_FH *fhp;
  58. {
  59. struct flock k_lock;
  60. int locked, ms, waited;
  61. if (!dbenv->db_mutexlocks)
  62. return (0);
  63. /* Initialize the lock. */
  64. k_lock.l_whence = SEEK_SET;
  65. k_lock.l_start = mutexp->off;
  66. k_lock.l_len = 1;
  67. for (locked = waited = 0;;) {
  68. /*
  69.  * Wait for the lock to become available; wait 1ms initially,
  70.  * up to 1 second.
  71.  */
  72. for (ms = 1; mutexp->pid != 0;) {
  73. waited = 1;
  74. __os_yield(NULL, ms * USEC_PER_MS);
  75. if ((ms <<= 1) > MS_PER_SEC)
  76. ms = MS_PER_SEC;
  77. }
  78. /* Acquire an exclusive kernel lock. */
  79. k_lock.l_type = F_WRLCK;
  80. if (fcntl(fhp->fd, F_SETLKW, &k_lock))
  81. return (__os_get_errno());
  82. /* If the resource is still available, it's ours. */
  83. if (mutexp->pid == 0) {
  84. locked = 1;
  85. mutexp->pid = (u_int32_t)getpid();
  86. }
  87. /* Release the kernel lock. */
  88. k_lock.l_type = F_UNLCK;
  89. if (fcntl(fhp->fd, F_SETLK, &k_lock))
  90. return (__os_get_errno());
  91. /*
  92.  * If we got the resource lock we're done.
  93.  *
  94.  * !!!
  95.  * We can't check to see if the lock is ours, because we may
  96.  * be trying to block ourselves in the lock manager, and so
  97.  * the holder of the lock that's preventing us from getting
  98.  * the lock may be us!  (Seriously.)
  99.  */
  100. if (locked)
  101. break;
  102. }
  103. if (waited)
  104. ++mutexp->mutex_set_wait;
  105. else
  106. ++mutexp->mutex_set_nowait;
  107. return (0);
  108. }
  109. /*
  110.  * __db_fcntl_mutex_unlock --
  111.  * Release a lock.
  112.  *
  113.  * PUBLIC: int __db_fcntl_mutex_unlock __P((DB_ENV *, MUTEX *));
  114.  */
  115. int
  116. __db_fcntl_mutex_unlock(dbenv, mutexp)
  117. DB_ENV *dbenv;
  118. MUTEX *mutexp;
  119. {
  120. if (!dbenv->db_mutexlocks)
  121. return (0);
  122. #ifdef DIAGNOSTIC
  123. #define MSG "mutex_unlock: ERROR: released lock that was unlockedn"
  124. #ifndef STDERR_FILENO
  125. #define STDERR_FILENO 2
  126. #endif
  127. if (mutexp->pid == 0)
  128. write(STDERR_FILENO, MSG, sizeof(MSG) - 1);
  129. #endif
  130. /*
  131.  * Release the resource.  We don't have to acquire any locks because
  132.  * processes trying to acquire the lock are checking for a pid set to
  133.  * 0/non-0, not to any specific value.
  134.  */
  135. mutexp->pid = 0;
  136. return (0);
  137. }
  138. /*
  139.  * __db_fcntl_mutex_destroy --
  140.  * Destroy a MUTEX.
  141.  *
  142.  * PUBLIC: int __db_fcntl_mutex_destroy __P((MUTEX *));
  143.  */
  144. int
  145. __db_fcntl_mutex_destroy(mutexp)
  146. MUTEX *mutexp;
  147. {
  148. COMPQUIET(mutexp, NULL);
  149. return (0);
  150. }