00001 /* 00002 ** 2007 August 28 00003 ** 00004 ** The author disclaims copyright to this source code. In place of 00005 ** a legal notice, here is a blessing: 00006 ** 00007 ** May you do good and not evil. 00008 ** May you find forgiveness for yourself and forgive others. 00009 ** May you share freely, never taking more than you give. 00010 ** 00011 ************************************************************************* 00012 ** This file contains the C functions that implement mutexes for OS/2 00013 ** 00014 ** $Id: mutex_os2.c,v 1.10 2008/06/23 22:13:28 pweilbacher Exp $ 00015 */ 00016 #include "sqliteInt.h" 00017 00018 /* 00019 ** The code in this file is only used if SQLITE_MUTEX_OS2 is defined. 00020 ** See the mutex.h file for details. 00021 */ 00022 #ifdef SQLITE_MUTEX_OS2 00023 00024 /********************** OS/2 Mutex Implementation ********************** 00025 ** 00026 ** This implementation of mutexes is built using the OS/2 API. 00027 */ 00028 00029 /* 00030 ** The mutex object 00031 ** Each recursive mutex is an instance of the following structure. 00032 */ 00033 struct sqlite3_mutex { 00034 HMTX mutex; /* Mutex controlling the lock */ 00035 int id; /* Mutex type */ 00036 int nRef; /* Number of references */ 00037 TID owner; /* Thread holding this mutex */ 00038 }; 00039 00040 #define OS2_MUTEX_INITIALIZER 0,0,0,0 00041 00042 /* 00043 ** Initialize and deinitialize the mutex subsystem. 00044 */ 00045 static int os2MutexInit(void){ return SQLITE_OK; } 00046 static int os2MutexEnd(void){ return SQLITE_OK; } 00047 00048 /* 00049 ** The sqlite3_mutex_alloc() routine allocates a new 00050 ** mutex and returns a pointer to it. If it returns NULL 00051 ** that means that a mutex could not be allocated. 00052 ** SQLite will unwind its stack and return an error. The argument 00053 ** to sqlite3_mutex_alloc() is one of these integer constants: 00054 ** 00055 ** <ul> 00056 ** <li> SQLITE_MUTEX_FAST 0 00057 ** <li> SQLITE_MUTEX_RECURSIVE 1 00058 ** <li> SQLITE_MUTEX_STATIC_MASTER 2 00059 ** <li> SQLITE_MUTEX_STATIC_MEM 3 00060 ** <li> SQLITE_MUTEX_STATIC_PRNG 4 00061 ** </ul> 00062 ** 00063 ** The first two constants cause sqlite3_mutex_alloc() to create 00064 ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE 00065 ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. 00066 ** The mutex implementation does not need to make a distinction 00067 ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does 00068 ** not want to. But SQLite will only request a recursive mutex in 00069 ** cases where it really needs one. If a faster non-recursive mutex 00070 ** implementation is available on the host platform, the mutex subsystem 00071 ** might return such a mutex in response to SQLITE_MUTEX_FAST. 00072 ** 00073 ** The other allowed parameters to sqlite3_mutex_alloc() each return 00074 ** a pointer to a static preexisting mutex. Three static mutexes are 00075 ** used by the current version of SQLite. Future versions of SQLite 00076 ** may add additional static mutexes. Static mutexes are for internal 00077 ** use by SQLite only. Applications that use SQLite mutexes should 00078 ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or 00079 ** SQLITE_MUTEX_RECURSIVE. 00080 ** 00081 ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST 00082 ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() 00083 ** returns a different mutex on every call. But for the static 00084 ** mutex types, the same mutex is returned on every call that has 00085 ** the same type number. 00086 */ 00087 static sqlite3_mutex *os2MutexAlloc(int iType){ 00088 sqlite3_mutex *p = NULL; 00089 switch( iType ){ 00090 case SQLITE_MUTEX_FAST: 00091 case SQLITE_MUTEX_RECURSIVE: { 00092 p = sqlite3MallocZero( sizeof(*p) ); 00093 if( p ){ 00094 p->id = iType; 00095 if( DosCreateMutexSem( 0, &p->mutex, 0, FALSE ) != NO_ERROR ){ 00096 sqlite3_free( p ); 00097 p = NULL; 00098 } 00099 } 00100 break; 00101 } 00102 default: { 00103 static volatile int isInit = 0; 00104 static sqlite3_mutex staticMutexes[] = { 00105 { OS2_MUTEX_INITIALIZER, }, 00106 { OS2_MUTEX_INITIALIZER, }, 00107 { OS2_MUTEX_INITIALIZER, }, 00108 { OS2_MUTEX_INITIALIZER, }, 00109 { OS2_MUTEX_INITIALIZER, }, 00110 { OS2_MUTEX_INITIALIZER, }, 00111 }; 00112 if ( !isInit ){ 00113 APIRET rc; 00114 PTIB ptib; 00115 PPIB ppib; 00116 HMTX mutex; 00117 char name[32]; 00118 DosGetInfoBlocks( &ptib, &ppib ); 00119 sqlite3_snprintf( sizeof(name), name, "\\SEM32\\SQLITE%04x", 00120 ppib->pib_ulpid ); 00121 while( !isInit ){ 00122 mutex = 0; 00123 rc = DosCreateMutexSem( name, &mutex, 0, FALSE); 00124 if( rc == NO_ERROR ){ 00125 int i; 00126 if( !isInit ){ 00127 for( i = 0; i < sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++ ){ 00128 DosCreateMutexSem( 0, &staticMutexes[i].mutex, 0, FALSE ); 00129 } 00130 isInit = 1; 00131 } 00132 DosCloseMutexSem( mutex ); 00133 }else if( rc == ERROR_DUPLICATE_NAME ){ 00134 DosSleep( 1 ); 00135 }else{ 00136 return p; 00137 } 00138 } 00139 } 00140 assert( iType-2 >= 0 ); 00141 assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) ); 00142 p = &staticMutexes[iType-2]; 00143 p->id = iType; 00144 break; 00145 } 00146 } 00147 return p; 00148 } 00149 00150 00151 /* 00152 ** This routine deallocates a previously allocated mutex. 00153 ** SQLite is careful to deallocate every mutex that it allocates. 00154 */ 00155 static void os2MutexFree(sqlite3_mutex *p){ 00156 if( p==0 ) return; 00157 assert( p->nRef==0 ); 00158 assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); 00159 DosCloseMutexSem( p->mutex ); 00160 sqlite3_free( p ); 00161 } 00162 00163 /* 00164 ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt 00165 ** to enter a mutex. If another thread is already within the mutex, 00166 ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return 00167 ** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK 00168 ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can 00169 ** be entered multiple times by the same thread. In such cases the, 00170 ** mutex must be exited an equal number of times before another thread 00171 ** can enter. If the same thread tries to enter any other kind of mutex 00172 ** more than once, the behavior is undefined. 00173 */ 00174 static void os2MutexEnter(sqlite3_mutex *p){ 00175 TID tid; 00176 PID holder1; 00177 ULONG holder2; 00178 if( p==0 ) return; 00179 assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) ); 00180 DosRequestMutexSem(p->mutex, SEM_INDEFINITE_WAIT); 00181 DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2); 00182 p->owner = tid; 00183 p->nRef++; 00184 } 00185 static int os2MutexTry(sqlite3_mutex *p){ 00186 int rc; 00187 TID tid; 00188 PID holder1; 00189 ULONG holder2; 00190 if( p==0 ) return SQLITE_OK; 00191 assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) ); 00192 if( DosRequestMutexSem(p->mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR) { 00193 DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2); 00194 p->owner = tid; 00195 p->nRef++; 00196 rc = SQLITE_OK; 00197 } else { 00198 rc = SQLITE_BUSY; 00199 } 00200 00201 return rc; 00202 } 00203 00204 /* 00205 ** The sqlite3_mutex_leave() routine exits a mutex that was 00206 ** previously entered by the same thread. The behavior 00207 ** is undefined if the mutex is not currently entered or 00208 ** is not currently allocated. SQLite will never do either. 00209 */ 00210 static void os2MutexLeave(sqlite3_mutex *p){ 00211 TID tid; 00212 PID holder1; 00213 ULONG holder2; 00214 if( p==0 ) return; 00215 assert( p->nRef>0 ); 00216 DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2); 00217 assert( p->owner==tid ); 00218 p->nRef--; 00219 assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); 00220 DosReleaseMutexSem(p->mutex); 00221 } 00222 00223 #ifdef SQLITE_DEBUG 00224 /* 00225 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are 00226 ** intended for use inside assert() statements. 00227 */ 00228 static int os2MutexHeld(sqlite3_mutex *p){ 00229 TID tid; 00230 PID pid; 00231 ULONG ulCount; 00232 PTIB ptib; 00233 if( p!=0 ) { 00234 DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); 00235 } else { 00236 DosGetInfoBlocks(&ptib, NULL); 00237 tid = ptib->tib_ptib2->tib2_ultid; 00238 } 00239 return p==0 || (p->nRef!=0 && p->owner==tid); 00240 } 00241 static int os2MutexNotheld(sqlite3_mutex *p){ 00242 TID tid; 00243 PID pid; 00244 ULONG ulCount; 00245 PTIB ptib; 00246 if( p!= 0 ) { 00247 DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); 00248 } else { 00249 DosGetInfoBlocks(&ptib, NULL); 00250 tid = ptib->tib_ptib2->tib2_ultid; 00251 } 00252 return p==0 || p->nRef==0 || p->owner!=tid; 00253 } 00254 #endif 00255 00256 sqlite3_mutex_methods *sqlite3DefaultMutex(void){ 00257 static sqlite3_mutex_methods sMutex = { 00258 os2MutexInit, 00259 os2MutexEnd, 00260 os2MutexAlloc, 00261 os2MutexFree, 00262 os2MutexEnter, 00263 os2MutexTry, 00264 os2MutexLeave, 00265 #ifdef SQLITE_DEBUG 00266 os2MutexHeld, 00267 os2MutexNotheld 00268 #endif 00269 }; 00270 00271 return &sMutex; 00272 } 00273 #endif /* SQLITE_MUTEX_OS2 */
ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:55 2011 by Doxygen 1.6.1