mutex.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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. ** The 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. But this implementation
  17. ** does do a lot of error checking on mutexes to make sure they
  18. ** are called correctly and at appropriate times. Hence, this
  19. ** implementation is suitable for testing.
  20. ** debugging purposes
  21. **
  22. ** $Id: mutex.c,v 1.16 2007/09/10 16:13:00 danielk1977 Exp $
  23. */
  24. #include "sqliteInt.h"
  25. #ifdef SQLITE_MUTEX_NOOP_DEBUG
  26. /*
  27. ** In this implementation, mutexes do not provide any mutual exclusion.
  28. ** But the error checking is provided. This implementation is useful
  29. ** for test purposes.
  30. */
  31. /*
  32. ** The mutex object
  33. */
  34. struct sqlite3_mutex {
  35. int id; /* The mutex type */
  36. int cnt; /* Number of entries without a matching leave */
  37. };
  38. /*
  39. ** The sqlite3_mutex_alloc() routine allocates a new
  40. ** mutex and returns a pointer to it. If it returns NULL
  41. ** that means that a mutex could not be allocated.
  42. */
  43. sqlite3_mutex *sqlite3_mutex_alloc(int id){
  44. static sqlite3_mutex aStatic[5];
  45. sqlite3_mutex *pNew = 0;
  46. switch( id ){
  47. case SQLITE_MUTEX_FAST:
  48. case SQLITE_MUTEX_RECURSIVE: {
  49. pNew = sqlite3_malloc(sizeof(*pNew));
  50. if( pNew ){
  51. pNew->id = id;
  52. pNew->cnt = 0;
  53. }
  54. break;
  55. }
  56. default: {
  57. assert( id-2 >= 0 );
  58. assert( id-2 < sizeof(aStatic)/sizeof(aStatic[0]) );
  59. pNew = &aStatic[id-2];
  60. pNew->id = id;
  61. break;
  62. }
  63. }
  64. return pNew;
  65. }
  66. /*
  67. ** This routine deallocates a previously allocated mutex.
  68. */
  69. void sqlite3_mutex_free(sqlite3_mutex *p){
  70. assert( p );
  71. assert( p->cnt==0 );
  72. assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
  73. sqlite3_free(p);
  74. }
  75. /*
  76. ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
  77. ** to enter a mutex. If another thread is already within the mutex,
  78. ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
  79. ** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
  80. ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
  81. ** be entered multiple times by the same thread. In such cases the,
  82. ** mutex must be exited an equal number of times before another thread
  83. ** can enter. If the same thread tries to enter any other kind of mutex
  84. ** more than once, the behavior is undefined.
  85. */
  86. void sqlite3_mutex_enter(sqlite3_mutex *p){
  87. assert( p );
  88. assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
  89. p->cnt++;
  90. }
  91. int sqlite3_mutex_try(sqlite3_mutex *p){
  92. assert( p );
  93. assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
  94. p->cnt++;
  95. return SQLITE_OK;
  96. }
  97. /*
  98. ** The sqlite3_mutex_leave() routine exits a mutex that was
  99. ** previously entered by the same thread. The behavior
  100. ** is undefined if the mutex is not currently entered or
  101. ** is not currently allocated. SQLite will never do either.
  102. */
  103. void sqlite3_mutex_leave(sqlite3_mutex *p){
  104. assert( p );
  105. assert( sqlite3_mutex_held(p) );
  106. p->cnt--;
  107. assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
  108. }
  109. /*
  110. ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
  111. ** intended for use inside assert() statements.
  112. */
  113. int sqlite3_mutex_held(sqlite3_mutex *p){
  114. return p==0 || p->cnt>0;
  115. }
  116. int sqlite3_mutex_notheld(sqlite3_mutex *p){
  117. return p==0 || p->cnt==0;
  118. }
  119. #endif /* SQLITE_MUTEX_NOOP_DEBUG */