extensions/sqlite/sqlite-source/mutex_unix.c
author Matt Woodrow <pred@alliedmods.net>
Wed Apr 16 05:41:34 2008 +0000 (2008-04-16)
changeset 2005 92033efef85f
parent 1952 b7aa2b626807
permissions -rw-r--r--
Added amb1609 - Persistant option to TF2_SetPlayerClass
ds@1952
     1
/*
ds@1952
     2
** 2007 August 28
ds@1952
     3
**
ds@1952
     4
** The author disclaims copyright to this source code.  In place of
ds@1952
     5
** a legal notice, here is a blessing:
ds@1952
     6
**
ds@1952
     7
**    May you do good and not evil.
ds@1952
     8
**    May you find forgiveness for yourself and forgive others.
ds@1952
     9
**    May you share freely, never taking more than you give.
ds@1952
    10
**
ds@1952
    11
*************************************************************************
ds@1952
    12
** This file contains the C functions that implement mutexes for pthreads
ds@1952
    13
**
ds@1952
    14
** $Id$
ds@1952
    15
*/
ds@1952
    16
#include "sqliteInt.h"
ds@1952
    17
ds@1952
    18
/*
ds@1952
    19
** The code in this file is only used if we are compiling threadsafe
ds@1952
    20
** under unix with pthreads.
ds@1952
    21
**
ds@1952
    22
** Note that this implementation requires a version of pthreads that
ds@1952
    23
** supports recursive mutexes.
ds@1952
    24
*/
ds@1952
    25
#ifdef SQLITE_MUTEX_PTHREADS
ds@1952
    26
ds@1952
    27
#include <pthread.h>
ds@1952
    28
ds@1952
    29
/*
ds@1952
    30
** Each recursive mutex is an instance of the following structure.
ds@1952
    31
*/
ds@1952
    32
struct sqlite3_mutex {
ds@1952
    33
  pthread_mutex_t mutex;     /* Mutex controlling the lock */
ds@1952
    34
  int id;                    /* Mutex type */
ds@1952
    35
  int nRef;                  /* Number of entrances */
ds@1952
    36
  pthread_t owner;           /* Thread that is within this mutex */
ds@1952
    37
#ifdef SQLITE_DEBUG
ds@1952
    38
  int trace;                 /* True to trace changes */
ds@1952
    39
#endif
ds@1952
    40
};
ds@1952
    41
ds@1952
    42
/*
ds@1952
    43
** The sqlite3_mutex_alloc() routine allocates a new
ds@1952
    44
** mutex and returns a pointer to it.  If it returns NULL
ds@1952
    45
** that means that a mutex could not be allocated.  SQLite
ds@1952
    46
** will unwind its stack and return an error.  The argument
ds@1952
    47
** to sqlite3_mutex_alloc() is one of these integer constants:
ds@1952
    48
**
ds@1952
    49
** <ul>
ds@1952
    50
** <li>  SQLITE_MUTEX_FAST
ds@1952
    51
** <li>  SQLITE_MUTEX_RECURSIVE
ds@1952
    52
** <li>  SQLITE_MUTEX_STATIC_MASTER
ds@1952
    53
** <li>  SQLITE_MUTEX_STATIC_MEM
ds@1952
    54
** <li>  SQLITE_MUTEX_STATIC_MEM2
ds@1952
    55
** <li>  SQLITE_MUTEX_STATIC_PRNG
ds@1952
    56
** <li>  SQLITE_MUTEX_STATIC_LRU
ds@1952
    57
** </ul>
ds@1952
    58
**
ds@1952
    59
** The first two constants cause sqlite3_mutex_alloc() to create
ds@1952
    60
** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
ds@1952
    61
** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
ds@1952
    62
** The mutex implementation does not need to make a distinction
ds@1952
    63
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
ds@1952
    64
** not want to.  But SQLite will only request a recursive mutex in
ds@1952
    65
** cases where it really needs one.  If a faster non-recursive mutex
ds@1952
    66
** implementation is available on the host platform, the mutex subsystem
ds@1952
    67
** might return such a mutex in response to SQLITE_MUTEX_FAST.
ds@1952
    68
**
ds@1952
    69
** The other allowed parameters to sqlite3_mutex_alloc() each return
ds@1952
    70
** a pointer to a static preexisting mutex.  Three static mutexes are
ds@1952
    71
** used by the current version of SQLite.  Future versions of SQLite
ds@1952
    72
** may add additional static mutexes.  Static mutexes are for internal
ds@1952
    73
** use by SQLite only.  Applications that use SQLite mutexes should
ds@1952
    74
** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
ds@1952
    75
** SQLITE_MUTEX_RECURSIVE.
ds@1952
    76
**
ds@1952
    77
** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
ds@1952
    78
** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
ds@1952
    79
** returns a different mutex on every call.  But for the static 
ds@1952
    80
** mutex types, the same mutex is returned on every call that has
ds@1952
    81
** the same type number.
ds@1952
    82
*/
ds@1952
    83
sqlite3_mutex *sqlite3_mutex_alloc(int iType){
ds@1952
    84
  static sqlite3_mutex staticMutexes[] = {
ds@1952
    85
    { PTHREAD_MUTEX_INITIALIZER, },
ds@1952
    86
    { PTHREAD_MUTEX_INITIALIZER, },
ds@1952
    87
    { PTHREAD_MUTEX_INITIALIZER, },
ds@1952
    88
    { PTHREAD_MUTEX_INITIALIZER, },
ds@1952
    89
    { PTHREAD_MUTEX_INITIALIZER, },
ds@1952
    90
  };
ds@1952
    91
  sqlite3_mutex *p;
ds@1952
    92
  switch( iType ){
ds@1952
    93
    case SQLITE_MUTEX_RECURSIVE: {
ds@1952
    94
      p = sqlite3MallocZero( sizeof(*p) );
ds@1952
    95
      if( p ){
ds@1952
    96
        pthread_mutexattr_t recursiveAttr;
ds@1952
    97
        pthread_mutexattr_init(&recursiveAttr);
ds@1952
    98
        pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE);
ds@1952
    99
        pthread_mutex_init(&p->mutex, &recursiveAttr);
ds@1952
   100
        pthread_mutexattr_destroy(&recursiveAttr);
ds@1952
   101
        p->id = iType;
ds@1952
   102
      }
ds@1952
   103
      break;
ds@1952
   104
    }
ds@1952
   105
    case SQLITE_MUTEX_FAST: {
ds@1952
   106
      p = sqlite3MallocZero( sizeof(*p) );
ds@1952
   107
      if( p ){
ds@1952
   108
        p->id = iType;
ds@1952
   109
        pthread_mutex_init(&p->mutex, 0);
ds@1952
   110
      }
ds@1952
   111
      break;
ds@1952
   112
    }
ds@1952
   113
    default: {
ds@1952
   114
      assert( iType-2 >= 0 );
ds@1952
   115
      assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) );
ds@1952
   116
      p = &staticMutexes[iType-2];
ds@1952
   117
      p->id = iType;
ds@1952
   118
      break;
ds@1952
   119
    }
ds@1952
   120
  }
ds@1952
   121
  return p;
ds@1952
   122
}
ds@1952
   123
ds@1952
   124
ds@1952
   125
/*
ds@1952
   126
** This routine deallocates a previously
ds@1952
   127
** allocated mutex.  SQLite is careful to deallocate every
ds@1952
   128
** mutex that it allocates.
ds@1952
   129
*/
ds@1952
   130
void sqlite3_mutex_free(sqlite3_mutex *p){
ds@1952
   131
  assert( p );
ds@1952
   132
  assert( p->nRef==0 );
ds@1952
   133
  assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
ds@1952
   134
  pthread_mutex_destroy(&p->mutex);
ds@1952
   135
  sqlite3_free(p);
ds@1952
   136
}
ds@1952
   137
ds@1952
   138
/*
ds@1952
   139
** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
ds@1952
   140
** to enter a mutex.  If another thread is already within the mutex,
ds@1952
   141
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
ds@1952
   142
** SQLITE_BUSY.  The sqlite3_mutex_try() interface returns SQLITE_OK
ds@1952
   143
** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
ds@1952
   144
** be entered multiple times by the same thread.  In such cases the,
ds@1952
   145
** mutex must be exited an equal number of times before another thread
ds@1952
   146
** can enter.  If the same thread tries to enter any other kind of mutex
ds@1952
   147
** more than once, the behavior is undefined.
ds@1952
   148
*/
ds@1952
   149
void sqlite3_mutex_enter(sqlite3_mutex *p){
ds@1952
   150
  assert( p );
ds@1952
   151
  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
ds@1952
   152
  pthread_mutex_lock(&p->mutex);
ds@1952
   153
  p->owner = pthread_self();
ds@1952
   154
  p->nRef++;
ds@1952
   155
#ifdef SQLITE_DEBUG
ds@1952
   156
  if( p->trace ){
ds@1952
   157
    printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
ds@1952
   158
  }
ds@1952
   159
#endif
ds@1952
   160
}
ds@1952
   161
int sqlite3_mutex_try(sqlite3_mutex *p){
ds@1952
   162
  int rc;
ds@1952
   163
  assert( p );
ds@1952
   164
  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
ds@1952
   165
  if( pthread_mutex_trylock(&p->mutex)==0 ){
ds@1952
   166
    p->owner = pthread_self();
ds@1952
   167
    p->nRef++;
ds@1952
   168
    rc = SQLITE_OK;
ds@1952
   169
#ifdef SQLITE_DEBUG
ds@1952
   170
    if( p->trace ){
ds@1952
   171
      printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
ds@1952
   172
    }
ds@1952
   173
#endif
ds@1952
   174
  }else{
ds@1952
   175
    rc = SQLITE_BUSY;
ds@1952
   176
  }
ds@1952
   177
  return rc;
ds@1952
   178
}
ds@1952
   179
ds@1952
   180
/*
ds@1952
   181
** The sqlite3_mutex_leave() routine exits a mutex that was
ds@1952
   182
** previously entered by the same thread.  The behavior
ds@1952
   183
** is undefined if the mutex is not currently entered or
ds@1952
   184
** is not currently allocated.  SQLite will never do either.
ds@1952
   185
*/
ds@1952
   186
void sqlite3_mutex_leave(sqlite3_mutex *p){
ds@1952
   187
  assert( p );
ds@1952
   188
  assert( sqlite3_mutex_held(p) );
ds@1952
   189
  p->nRef--;
ds@1952
   190
  assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
ds@1952
   191
#ifdef SQLITE_DEBUG
ds@1952
   192
  if( p->trace ){
ds@1952
   193
    printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
ds@1952
   194
  }
ds@1952
   195
#endif
ds@1952
   196
  pthread_mutex_unlock(&p->mutex);
ds@1952
   197
}
ds@1952
   198
ds@1952
   199
/*
ds@1952
   200
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
ds@1952
   201
** intended for use only inside assert() statements.  On some platforms,
ds@1952
   202
** there might be race conditions that can cause these routines to
ds@1952
   203
** deliver incorrect results.  In particular, if pthread_equal() is
ds@1952
   204
** not an atomic operation, then these routines might delivery
ds@1952
   205
** incorrect results.  On most platforms, pthread_equal() is a 
ds@1952
   206
** comparison of two integers and is therefore atomic.  But we are
ds@1952
   207
** told that HPUX is not such a platform.  If so, then these routines
ds@1952
   208
** will not always work correctly on HPUX.
ds@1952
   209
**
ds@1952
   210
** On those platforms where pthread_equal() is not atomic, SQLite
ds@1952
   211
** should be compiled without -DSQLITE_DEBUG and with -DNDEBUG to
ds@1952
   212
** make sure no assert() statements are evaluated and hence these
ds@1952
   213
** routines are never called.
ds@1952
   214
*/
ds@1952
   215
#ifndef NDEBUG
ds@1952
   216
int sqlite3_mutex_held(sqlite3_mutex *p){
ds@1952
   217
  return p==0 || (p->nRef!=0 && pthread_equal(p->owner, pthread_self()));
ds@1952
   218
}
ds@1952
   219
int sqlite3_mutex_notheld(sqlite3_mutex *p){
ds@1952
   220
  return p==0 || p->nRef==0 || pthread_equal(p->owner, pthread_self())==0;
ds@1952
   221
}
ds@1952
   222
#endif
ds@1952
   223
#endif /* SQLITE_MUTEX_PTHREAD */