mutex.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. ** 2007 August 14
  3. **
  4. ** The author disclaims copyright to this source code. In place of
  5. ** a legal notice, here is a blessing:
  6. **
  7. ** May you do good and not evil.
  8. ** May you find forgiveness for yourself and forgive others.
  9. ** May you share freely, never taking more than you give.
  10. **
  11. *************************************************************************
  12. ** This file contains the C functions that implement mutexes.
  13. **
  14. ** This file contains code that is common across all mutex implementations.
  15. */
  16. #include "sqliteInt.h"
  17. #if defined(SQLITE_DEBUG) && !defined(SQLITE_MUTEX_OMIT)
  18. /*
  19. ** For debugging purposes, record when the mutex subsystem is initialized
  20. ** and uninitialized so that we can assert() if there is an attempt to
  21. ** allocate a mutex while the system is uninitialized.
  22. */
  23. static SQLITE_WSD int mutexIsInit = 0;
  24. #endif /* SQLITE_DEBUG */
  25. #ifndef SQLITE_MUTEX_OMIT
  26. /*
  27. ** Initialize the mutex system.
  28. */
  29. int sqlite3MutexInit(void){
  30. int rc = SQLITE_OK;
  31. if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){
  32. /* If the xMutexAlloc method has not been set, then the user did not
  33. ** install a mutex implementation via sqlite3_config() prior to
  34. ** sqlite3_initialize() being called. This block copies pointers to
  35. ** the default implementation into the sqlite3GlobalConfig structure.
  36. */
  37. sqlite3_mutex_methods const *pFrom;
  38. sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex;
  39. if( sqlite3GlobalConfig.bCoreMutex ){
  40. pFrom = sqlite3DefaultMutex();
  41. }else{
  42. pFrom = sqlite3NoopMutex();
  43. }
  44. memcpy(pTo, pFrom, offsetof(sqlite3_mutex_methods, xMutexAlloc));
  45. memcpy(&pTo->xMutexFree, &pFrom->xMutexFree,
  46. sizeof(*pTo) - offsetof(sqlite3_mutex_methods, xMutexFree));
  47. pTo->xMutexAlloc = pFrom->xMutexAlloc;
  48. }
  49. rc = sqlite3GlobalConfig.mutex.xMutexInit();
  50. #ifdef SQLITE_DEBUG
  51. GLOBAL(int, mutexIsInit) = 1;
  52. #endif
  53. return rc;
  54. }
  55. /*
  56. ** Shutdown the mutex system. This call frees resources allocated by
  57. ** sqlite3MutexInit().
  58. */
  59. int sqlite3MutexEnd(void){
  60. int rc = SQLITE_OK;
  61. if( sqlite3GlobalConfig.mutex.xMutexEnd ){
  62. rc = sqlite3GlobalConfig.mutex.xMutexEnd();
  63. }
  64. #ifdef SQLITE_DEBUG
  65. GLOBAL(int, mutexIsInit) = 0;
  66. #endif
  67. return rc;
  68. }
  69. /*
  70. ** Retrieve a pointer to a static mutex or allocate a new dynamic one.
  71. */
  72. sqlite3_mutex *sqlite3_mutex_alloc(int id){
  73. #ifndef SQLITE_OMIT_AUTOINIT
  74. if( sqlite3_initialize() ) return 0;
  75. #endif
  76. return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
  77. }
  78. sqlite3_mutex *sqlite3MutexAlloc(int id){
  79. if( !sqlite3GlobalConfig.bCoreMutex ){
  80. return 0;
  81. }
  82. assert( GLOBAL(int, mutexIsInit) );
  83. return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
  84. }
  85. /*
  86. ** Free a dynamic mutex.
  87. */
  88. void sqlite3_mutex_free(sqlite3_mutex *p){
  89. if( p ){
  90. sqlite3GlobalConfig.mutex.xMutexFree(p);
  91. }
  92. }
  93. /*
  94. ** Obtain the mutex p. If some other thread already has the mutex, block
  95. ** until it can be obtained.
  96. */
  97. void sqlite3_mutex_enter(sqlite3_mutex *p){
  98. if( p ){
  99. sqlite3GlobalConfig.mutex.xMutexEnter(p);
  100. }
  101. }
  102. /*
  103. ** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another
  104. ** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY.
  105. */
  106. int sqlite3_mutex_try(sqlite3_mutex *p){
  107. int rc = SQLITE_OK;
  108. if( p ){
  109. return sqlite3GlobalConfig.mutex.xMutexTry(p);
  110. }
  111. return rc;
  112. }
  113. /*
  114. ** The sqlite3_mutex_leave() routine exits a mutex that was previously
  115. ** entered by the same thread. The behavior is undefined if the mutex
  116. ** is not currently entered. If a NULL pointer is passed as an argument
  117. ** this function is a no-op.
  118. */
  119. void sqlite3_mutex_leave(sqlite3_mutex *p){
  120. if( p ){
  121. sqlite3GlobalConfig.mutex.xMutexLeave(p);
  122. }
  123. }
  124. #ifndef NDEBUG
  125. /*
  126. ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
  127. ** intended for use inside assert() statements.
  128. */
  129. int sqlite3_mutex_held(sqlite3_mutex *p){
  130. return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
  131. }
  132. int sqlite3_mutex_notheld(sqlite3_mutex *p){
  133. return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
  134. }
  135. #endif
  136. #endif /* !defined(SQLITE_MUTEX_OMIT) */