mutex_noop.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. ** 2008 October 07
  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 implementation in this file does not provide any mutual
  15. ** exclusion and is thus suitable for use only in applications
  16. ** that use SQLite in a single thread. The routines defined
  17. ** here are place-holders. Applications can substitute working
  18. ** mutex routines at start-time using the
  19. **
  20. ** sqlite3_config(SQLITE_CONFIG_MUTEX,...)
  21. **
  22. ** interface.
  23. **
  24. ** If compiled with SQLITE_DEBUG, then additional logic is inserted
  25. ** that does error checking on mutexes to make sure they are being
  26. ** called correctly.
  27. */
  28. #include "sqliteInt.h"
  29. #ifndef SQLITE_MUTEX_OMIT
  30. #ifndef SQLITE_DEBUG
  31. /*
  32. ** Stub routines for all mutex methods.
  33. **
  34. ** This routines provide no mutual exclusion or error checking.
  35. */
  36. static int noopMutexInit(void){ return SQLITE_OK; }
  37. static int noopMutexEnd(void){ return SQLITE_OK; }
  38. static sqlite3_mutex *noopMutexAlloc(int id){
  39. UNUSED_PARAMETER(id);
  40. return (sqlite3_mutex*)8;
  41. }
  42. static void noopMutexFree(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; }
  43. static void noopMutexEnter(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; }
  44. static int noopMutexTry(sqlite3_mutex *p){
  45. UNUSED_PARAMETER(p);
  46. return SQLITE_OK;
  47. }
  48. static void noopMutexLeave(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; }
  49. sqlite3_mutex_methods const *sqlite3NoopMutex(void){
  50. static const sqlite3_mutex_methods sMutex = {
  51. noopMutexInit,
  52. noopMutexEnd,
  53. noopMutexAlloc,
  54. noopMutexFree,
  55. noopMutexEnter,
  56. noopMutexTry,
  57. noopMutexLeave,
  58. 0,
  59. 0,
  60. };
  61. return &sMutex;
  62. }
  63. #endif /* !SQLITE_DEBUG */
  64. #ifdef SQLITE_DEBUG
  65. /*
  66. ** In this implementation, error checking is provided for testing
  67. ** and debugging purposes. The mutexes still do not provide any
  68. ** mutual exclusion.
  69. */
  70. /*
  71. ** The mutex object
  72. */
  73. typedef struct sqlite3_debug_mutex {
  74. int id; /* The mutex type */
  75. int cnt; /* Number of entries without a matching leave */
  76. } sqlite3_debug_mutex;
  77. /*
  78. ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
  79. ** intended for use inside assert() statements.
  80. */
  81. static int debugMutexHeld(sqlite3_mutex *pX){
  82. sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
  83. return p==0 || p->cnt>0;
  84. }
  85. static int debugMutexNotheld(sqlite3_mutex *pX){
  86. sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
  87. return p==0 || p->cnt==0;
  88. }
  89. /*
  90. ** Initialize and deinitialize the mutex subsystem.
  91. */
  92. static int debugMutexInit(void){ return SQLITE_OK; }
  93. static int debugMutexEnd(void){ return SQLITE_OK; }
  94. /*
  95. ** The sqlite3_mutex_alloc() routine allocates a new
  96. ** mutex and returns a pointer to it. If it returns NULL
  97. ** that means that a mutex could not be allocated.
  98. */
  99. static sqlite3_mutex *debugMutexAlloc(int id){
  100. static sqlite3_debug_mutex aStatic[6];
  101. sqlite3_debug_mutex *pNew = 0;
  102. switch( id ){
  103. case SQLITE_MUTEX_FAST:
  104. case SQLITE_MUTEX_RECURSIVE: {
  105. pNew = sqlite3Malloc(sizeof(*pNew));
  106. if( pNew ){
  107. pNew->id = id;
  108. pNew->cnt = 0;
  109. }
  110. break;
  111. }
  112. default: {
  113. assert( id-2 >= 0 );
  114. assert( id-2 < (int)(sizeof(aStatic)/sizeof(aStatic[0])) );
  115. pNew = &aStatic[id-2];
  116. pNew->id = id;
  117. break;
  118. }
  119. }
  120. return (sqlite3_mutex*)pNew;
  121. }
  122. /*
  123. ** This routine deallocates a previously allocated mutex.
  124. */
  125. static void debugMutexFree(sqlite3_mutex *pX){
  126. sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
  127. assert( p->cnt==0 );
  128. assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
  129. sqlite3_free(p);
  130. }
  131. /*
  132. ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
  133. ** to enter a mutex. If another thread is already within the mutex,
  134. ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
  135. ** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
  136. ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
  137. ** be entered multiple times by the same thread. In such cases the,
  138. ** mutex must be exited an equal number of times before another thread
  139. ** can enter. If the same thread tries to enter any other kind of mutex
  140. ** more than once, the behavior is undefined.
  141. */
  142. static void debugMutexEnter(sqlite3_mutex *pX){
  143. sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
  144. assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
  145. p->cnt++;
  146. }
  147. static int debugMutexTry(sqlite3_mutex *pX){
  148. sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
  149. assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
  150. p->cnt++;
  151. return SQLITE_OK;
  152. }
  153. /*
  154. ** The sqlite3_mutex_leave() routine exits a mutex that was
  155. ** previously entered by the same thread. The behavior
  156. ** is undefined if the mutex is not currently entered or
  157. ** is not currently allocated. SQLite will never do either.
  158. */
  159. static void debugMutexLeave(sqlite3_mutex *pX){
  160. sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
  161. assert( debugMutexHeld(pX) );
  162. p->cnt--;
  163. assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
  164. }
  165. sqlite3_mutex_methods const *sqlite3NoopMutex(void){
  166. static const sqlite3_mutex_methods sMutex = {
  167. debugMutexInit,
  168. debugMutexEnd,
  169. debugMutexAlloc,
  170. debugMutexFree,
  171. debugMutexEnter,
  172. debugMutexTry,
  173. debugMutexLeave,
  174. debugMutexHeld,
  175. debugMutexNotheld
  176. };
  177. return &sMutex;
  178. }
  179. #endif /* SQLITE_DEBUG */
  180. /*
  181. ** If compiled with SQLITE_MUTEX_NOOP, then the no-op mutex implementation
  182. ** is used regardless of the run-time threadsafety setting.
  183. */
  184. #ifdef SQLITE_MUTEX_NOOP
  185. sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
  186. return sqlite3NoopMutex();
  187. }
  188. #endif /* defined(SQLITE_MUTEX_NOOP) */
  189. #endif /* !defined(SQLITE_MUTEX_OMIT) */