mutex_unix.c.svn-base
上传用户:sunhongbo
上传日期:2022-01-25
资源大小:3010k
文件大小:10k
源码类别:

数据库系统

开发平台:

C/C++

  1. /*
  2. ** 2007 August 28
  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 for pthreads
  13. **
  14. ** $Id: mutex_unix.c,v 1.7 2008/03/29 12:47:27 rse Exp $
  15. */
  16. #include "sqliteInt.h"
  17. /*
  18. ** The code in this file is only used if we are compiling threadsafe
  19. ** under unix with pthreads.
  20. **
  21. ** Note that this implementation requires a version of pthreads that
  22. ** supports recursive mutexes.
  23. */
  24. #ifdef SQLITE_MUTEX_PTHREADS
  25. #include <pthread.h>
  26. /*
  27. ** Each recursive mutex is an instance of the following structure.
  28. */
  29. struct sqlite3_mutex {
  30.   pthread_mutex_t mutex;     /* Mutex controlling the lock */
  31.   int id;                    /* Mutex type */
  32.   int nRef;                  /* Number of entrances */
  33.   pthread_t owner;           /* Thread that is within this mutex */
  34. #ifdef SQLITE_DEBUG
  35.   int trace;                 /* True to trace changes */
  36. #endif
  37. };
  38. #ifdef SQLITE_DEBUG
  39. #define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0, 0 }
  40. #else
  41. #define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0 }
  42. #endif
  43. /*
  44. ** The sqlite3_mutex_alloc() routine allocates a new
  45. ** mutex and returns a pointer to it.  If it returns NULL
  46. ** that means that a mutex could not be allocated.  SQLite
  47. ** will unwind its stack and return an error.  The argument
  48. ** to sqlite3_mutex_alloc() is one of these integer constants:
  49. **
  50. ** <ul>
  51. ** <li>  SQLITE_MUTEX_FAST
  52. ** <li>  SQLITE_MUTEX_RECURSIVE
  53. ** <li>  SQLITE_MUTEX_STATIC_MASTER
  54. ** <li>  SQLITE_MUTEX_STATIC_MEM
  55. ** <li>  SQLITE_MUTEX_STATIC_MEM2
  56. ** <li>  SQLITE_MUTEX_STATIC_PRNG
  57. ** <li>  SQLITE_MUTEX_STATIC_LRU
  58. ** </ul>
  59. **
  60. ** The first two constants cause sqlite3_mutex_alloc() to create
  61. ** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
  62. ** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
  63. ** The mutex implementation does not need to make a distinction
  64. ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
  65. ** not want to.  But SQLite will only request a recursive mutex in
  66. ** cases where it really needs one.  If a faster non-recursive mutex
  67. ** implementation is available on the host platform, the mutex subsystem
  68. ** might return such a mutex in response to SQLITE_MUTEX_FAST.
  69. **
  70. ** The other allowed parameters to sqlite3_mutex_alloc() each return
  71. ** a pointer to a static preexisting mutex.  Three static mutexes are
  72. ** used by the current version of SQLite.  Future versions of SQLite
  73. ** may add additional static mutexes.  Static mutexes are for internal
  74. ** use by SQLite only.  Applications that use SQLite mutexes should
  75. ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
  76. ** SQLITE_MUTEX_RECURSIVE.
  77. **
  78. ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
  79. ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
  80. ** returns a different mutex on every call.  But for the static 
  81. ** mutex types, the same mutex is returned on every call that has
  82. ** the same type number.
  83. */
  84. sqlite3_mutex *sqlite3_mutex_alloc(int iType){
  85.   static sqlite3_mutex staticMutexes[] = {
  86.     SQLITE3_MUTEX_INITIALIZER,
  87.     SQLITE3_MUTEX_INITIALIZER,
  88.     SQLITE3_MUTEX_INITIALIZER,
  89.     SQLITE3_MUTEX_INITIALIZER,
  90.     SQLITE3_MUTEX_INITIALIZER,
  91.     SQLITE3_MUTEX_INITIALIZER
  92.   };
  93.   sqlite3_mutex *p;
  94.   switch( iType ){
  95.     case SQLITE_MUTEX_RECURSIVE: {
  96.       p = sqlite3MallocZero( sizeof(*p) );
  97.       if( p ){
  98. #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
  99.         /* If recursive mutexes are not available, we will have to
  100.         ** build our own.  See below. */
  101.         pthread_mutex_init(&p->mutex, 0);
  102. #else
  103.         /* Use a recursive mutex if it is available */
  104.         pthread_mutexattr_t recursiveAttr;
  105.         pthread_mutexattr_init(&recursiveAttr);
  106.         pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE);
  107.         pthread_mutex_init(&p->mutex, &recursiveAttr);
  108.         pthread_mutexattr_destroy(&recursiveAttr);
  109. #endif
  110.         p->id = iType;
  111.       }
  112.       break;
  113.     }
  114.     case SQLITE_MUTEX_FAST: {
  115.       p = sqlite3MallocZero( sizeof(*p) );
  116.       if( p ){
  117.         p->id = iType;
  118.         pthread_mutex_init(&p->mutex, 0);
  119.       }
  120.       break;
  121.     }
  122.     default: {
  123.       assert( iType-2 >= 0 );
  124.       assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) );
  125.       p = &staticMutexes[iType-2];
  126.       p->id = iType;
  127.       break;
  128.     }
  129.   }
  130.   return p;
  131. }
  132. /*
  133. ** This routine deallocates a previously
  134. ** allocated mutex.  SQLite is careful to deallocate every
  135. ** mutex that it allocates.
  136. */
  137. void sqlite3_mutex_free(sqlite3_mutex *p){
  138.   assert( p );
  139.   assert( p->nRef==0 );
  140.   assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
  141.   pthread_mutex_destroy(&p->mutex);
  142.   sqlite3_free(p);
  143. }
  144. /*
  145. ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
  146. ** to enter a mutex.  If another thread is already within the mutex,
  147. ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
  148. ** SQLITE_BUSY.  The sqlite3_mutex_try() interface returns SQLITE_OK
  149. ** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
  150. ** be entered multiple times by the same thread.  In such cases the,
  151. ** mutex must be exited an equal number of times before another thread
  152. ** can enter.  If the same thread tries to enter any other kind of mutex
  153. ** more than once, the behavior is undefined.
  154. */
  155. void sqlite3_mutex_enter(sqlite3_mutex *p){
  156.   assert( p );
  157.   assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
  158. #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
  159.   /* If recursive mutexes are not available, then we have to grow
  160.   ** our own.  This implementation assumes that pthread_equal()
  161.   ** is atomic - that it cannot be deceived into thinking self
  162.   ** and p->owner are equal if p->owner changes between two values
  163.   ** that are not equal to self while the comparison is taking place.
  164.   ** This implementation also assumes a coherent cache - that 
  165.   ** separate processes cannot read different values from the same
  166.   ** address at the same time.  If either of these two conditions
  167.   ** are not met, then the mutexes will fail and problems will result.
  168.   */
  169.   {
  170.     pthread_t self = pthread_self();
  171.     if( p->nRef>0 && pthread_equal(p->owner, self) ){
  172.       p->nRef++;
  173.     }else{
  174.       pthread_mutex_lock(&p->mutex);
  175.       assert( p->nRef==0 );
  176.       p->owner = self;
  177.       p->nRef = 1;
  178.     }
  179.   }
  180. #else
  181.   /* Use the built-in recursive mutexes if they are available.
  182.   */
  183.   pthread_mutex_lock(&p->mutex);
  184.   p->owner = pthread_self();
  185.   p->nRef++;
  186. #endif
  187. #ifdef SQLITE_DEBUG
  188.   if( p->trace ){
  189.     printf("enter mutex %p (%d) with nRef=%dn", p, p->trace, p->nRef);
  190.   }
  191. #endif
  192. }
  193. int sqlite3_mutex_try(sqlite3_mutex *p){
  194.   int rc;
  195.   assert( p );
  196.   assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
  197. #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
  198.   /* If recursive mutexes are not available, then we have to grow
  199.   ** our own.  This implementation assumes that pthread_equal()
  200.   ** is atomic - that it cannot be deceived into thinking self
  201.   ** and p->owner are equal if p->owner changes between two values
  202.   ** that are not equal to self while the comparison is taking place.
  203.   ** This implementation also assumes a coherent cache - that 
  204.   ** separate processes cannot read different values from the same
  205.   ** address at the same time.  If either of these two conditions
  206.   ** are not met, then the mutexes will fail and problems will result.
  207.   */
  208.   {
  209.     pthread_t self = pthread_self();
  210.     if( p->nRef>0 && pthread_equal(p->owner, self) ){
  211.       p->nRef++;
  212.       rc = SQLITE_OK;
  213.     }else if( pthread_mutex_lock(&p->mutex)==0 ){
  214.       assert( p->nRef==0 );
  215.       p->owner = self;
  216.       p->nRef = 1;
  217.       rc = SQLITE_OK;
  218.     }else{
  219.       rc = SQLITE_BUSY;
  220.     }
  221.   }
  222. #else
  223.   /* Use the built-in recursive mutexes if they are available.
  224.   */
  225.   if( pthread_mutex_trylock(&p->mutex)==0 ){
  226.     p->owner = pthread_self();
  227.     p->nRef++;
  228.     rc = SQLITE_OK;
  229.   }else{
  230.     rc = SQLITE_BUSY;
  231.   }
  232. #endif
  233. #ifdef SQLITE_DEBUG
  234.   if( rc==SQLITE_OK && p->trace ){
  235.     printf("enter mutex %p (%d) with nRef=%dn", p, p->trace, p->nRef);
  236.   }
  237. #endif
  238.   return rc;
  239. }
  240. /*
  241. ** The sqlite3_mutex_leave() routine exits a mutex that was
  242. ** previously entered by the same thread.  The behavior
  243. ** is undefined if the mutex is not currently entered or
  244. ** is not currently allocated.  SQLite will never do either.
  245. */
  246. void sqlite3_mutex_leave(sqlite3_mutex *p){
  247.   assert( p );
  248.   assert( sqlite3_mutex_held(p) );
  249.   p->nRef--;
  250.   assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
  251. #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
  252.   if( p->nRef==0 ){
  253.     pthread_mutex_unlock(&p->mutex);
  254.   }
  255. #else
  256.   pthread_mutex_unlock(&p->mutex);
  257. #endif
  258. #ifdef SQLITE_DEBUG
  259.   if( p->trace ){
  260.     printf("leave mutex %p (%d) with nRef=%dn", p, p->trace, p->nRef);
  261.   }
  262. #endif
  263. }
  264. /*
  265. ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
  266. ** intended for use only inside assert() statements.  On some platforms,
  267. ** there might be race conditions that can cause these routines to
  268. ** deliver incorrect results.  In particular, if pthread_equal() is
  269. ** not an atomic operation, then these routines might delivery
  270. ** incorrect results.  On most platforms, pthread_equal() is a 
  271. ** comparison of two integers and is therefore atomic.  But we are
  272. ** told that HPUX is not such a platform.  If so, then these routines
  273. ** will not always work correctly on HPUX.
  274. **
  275. ** On those platforms where pthread_equal() is not atomic, SQLite
  276. ** should be compiled without -DSQLITE_DEBUG and with -DNDEBUG to
  277. ** make sure no assert() statements are evaluated and hence these
  278. ** routines are never called.
  279. */
  280. #ifndef NDEBUG
  281. int sqlite3_mutex_held(sqlite3_mutex *p){
  282.   return p==0 || (p->nRef!=0 && pthread_equal(p->owner, pthread_self()));
  283. }
  284. int sqlite3_mutex_notheld(sqlite3_mutex *p){
  285.   return p==0 || p->nRef==0 || pthread_equal(p->owner, pthread_self())==0;
  286. }
  287. #endif
  288. #endif /* SQLITE_MUTEX_PTHREAD */