4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
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.
11 *************************************************************************
12 ** This file contains the C functions that implement mutexes for OS/2
14 #include "sqliteInt.h"
17 ** The code in this file is only used if SQLITE_MUTEX_OS2 is defined.
18 ** See the mutex.h file for details.
20 #ifdef SQLITE_MUTEX_OS2
22 /********************** OS/2 Mutex Implementation **********************
24 ** This implementation of mutexes is built using the OS/2 API.
29 ** Each recursive mutex is an instance of the following structure.
31 struct sqlite3_mutex
{
32 HMTX mutex
; /* Mutex controlling the lock */
33 int id
; /* Mutex type */
35 int trace
; /* True to trace changes */
40 #define SQLITE3_MUTEX_INITIALIZER { 0, 0, 0 }
42 #define SQLITE3_MUTEX_INITIALIZER { 0, 0 }
46 ** Initialize and deinitialize the mutex subsystem.
48 static int os2MutexInit(void){ return SQLITE_OK
; }
49 static int os2MutexEnd(void){ return SQLITE_OK
; }
52 ** The sqlite3_mutex_alloc() routine allocates a new
53 ** mutex and returns a pointer to it. If it returns NULL
54 ** that means that a mutex could not be allocated.
55 ** SQLite will unwind its stack and return an error. The argument
56 ** to sqlite3_mutex_alloc() is one of these integer constants:
59 ** <li> SQLITE_MUTEX_FAST
60 ** <li> SQLITE_MUTEX_RECURSIVE
61 ** <li> SQLITE_MUTEX_STATIC_MASTER
62 ** <li> SQLITE_MUTEX_STATIC_MEM
63 ** <li> SQLITE_MUTEX_STATIC_MEM2
64 ** <li> SQLITE_MUTEX_STATIC_PRNG
65 ** <li> SQLITE_MUTEX_STATIC_LRU
66 ** <li> SQLITE_MUTEX_STATIC_LRU2
69 ** The first two constants cause sqlite3_mutex_alloc() to create
70 ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
71 ** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
72 ** The mutex implementation does not need to make a distinction
73 ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
74 ** not want to. But SQLite will only request a recursive mutex in
75 ** cases where it really needs one. If a faster non-recursive mutex
76 ** implementation is available on the host platform, the mutex subsystem
77 ** might return such a mutex in response to SQLITE_MUTEX_FAST.
79 ** The other allowed parameters to sqlite3_mutex_alloc() each return
80 ** a pointer to a static preexisting mutex. Six static mutexes are
81 ** used by the current version of SQLite. Future versions of SQLite
82 ** may add additional static mutexes. Static mutexes are for internal
83 ** use by SQLite only. Applications that use SQLite mutexes should
84 ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
85 ** SQLITE_MUTEX_RECURSIVE.
87 ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
88 ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
89 ** returns a different mutex on every call. But for the static
90 ** mutex types, the same mutex is returned on every call that has
91 ** the same type number.
93 static sqlite3_mutex
*os2MutexAlloc(int iType
){
94 sqlite3_mutex
*p
= NULL
;
96 case SQLITE_MUTEX_FAST
:
97 case SQLITE_MUTEX_RECURSIVE
: {
98 p
= sqlite3MallocZero( sizeof(*p
) );
101 if( DosCreateMutexSem( 0, &p
->mutex
, 0, FALSE
) != NO_ERROR
){
109 static volatile int isInit
= 0;
110 static sqlite3_mutex staticMutexes
[6] = {
111 SQLITE3_MUTEX_INITIALIZER
,
112 SQLITE3_MUTEX_INITIALIZER
,
113 SQLITE3_MUTEX_INITIALIZER
,
114 SQLITE3_MUTEX_INITIALIZER
,
115 SQLITE3_MUTEX_INITIALIZER
,
116 SQLITE3_MUTEX_INITIALIZER
,
124 DosGetInfoBlocks( &ptib
, &ppib
);
125 sqlite3_snprintf( sizeof(name
), name
, "\\SEM32\\SQLITE%04x",
129 rc
= DosCreateMutexSem( name
, &mutex
, 0, FALSE
);
130 if( rc
== NO_ERROR
){
133 for( i
= 0; i
< sizeof(staticMutexes
)/sizeof(staticMutexes
[0]); i
++ ){
134 DosCreateMutexSem( 0, &staticMutexes
[i
].mutex
, 0, FALSE
);
138 DosCloseMutexSem( mutex
);
139 }else if( rc
== ERROR_DUPLICATE_NAME
){
146 assert( iType
-2 >= 0 );
147 assert( iType
-2 < sizeof(staticMutexes
)/sizeof(staticMutexes
[0]) );
148 p
= &staticMutexes
[iType
-2];
158 ** This routine deallocates a previously allocated mutex.
159 ** SQLite is careful to deallocate every mutex that it allocates.
161 static void os2MutexFree(sqlite3_mutex
*p
){
166 DosQueryMutexSem(p
->mutex
, &pid
, &tid
, &ulCount
);
167 assert( ulCount
==0 );
168 assert( p
->id
==SQLITE_MUTEX_FAST
|| p
->id
==SQLITE_MUTEX_RECURSIVE
);
170 DosCloseMutexSem( p
->mutex
);
176 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
177 ** intended for use inside assert() statements.
179 static int os2MutexHeld(sqlite3_mutex
*p
){
184 DosQueryMutexSem(p
->mutex
, &pid
, &tid
, &ulCount
);
185 if( ulCount
==0 || ( ulCount
>1 && p
->id
!=SQLITE_MUTEX_RECURSIVE
) )
187 DosGetInfoBlocks(&ptib
, NULL
);
188 return tid
==ptib
->tib_ptib2
->tib2_ultid
;
190 static int os2MutexNotheld(sqlite3_mutex
*p
){
195 DosQueryMutexSem(p
->mutex
, &pid
, &tid
, &ulCount
);
198 DosGetInfoBlocks(&ptib
, NULL
);
199 return tid
!=ptib
->tib_ptib2
->tib2_ultid
;
201 static void os2MutexTrace(sqlite3_mutex
*p
, char *pAction
){
205 DosQueryMutexSem(p
->mutex
, &pid
, &tid
, &ulCount
);
206 printf("%s mutex %p (%d) with nRef=%ld\n", pAction
, (void*)p
, p
->trace
, ulCount
);
211 ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
212 ** to enter a mutex. If another thread is already within the mutex,
213 ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
214 ** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
215 ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
216 ** be entered multiple times by the same thread. In such cases the,
217 ** mutex must be exited an equal number of times before another thread
218 ** can enter. If the same thread tries to enter any other kind of mutex
219 ** more than once, the behavior is undefined.
221 static void os2MutexEnter(sqlite3_mutex
*p
){
222 assert( p
->id
==SQLITE_MUTEX_RECURSIVE
|| os2MutexNotheld(p
) );
223 DosRequestMutexSem(p
->mutex
, SEM_INDEFINITE_WAIT
);
225 if( p
->trace
) os2MutexTrace(p
, "enter");
228 static int os2MutexTry(sqlite3_mutex
*p
){
229 int rc
= SQLITE_BUSY
;
230 assert( p
->id
==SQLITE_MUTEX_RECURSIVE
|| os2MutexNotheld(p
) );
231 if( DosRequestMutexSem(p
->mutex
, SEM_IMMEDIATE_RETURN
) == NO_ERROR
) {
234 if( p
->trace
) os2MutexTrace(p
, "try");
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.
246 static void os2MutexLeave(sqlite3_mutex
*p
){
247 assert( os2MutexHeld(p
) );
248 DosReleaseMutexSem(p
->mutex
);
250 if( p
->trace
) os2MutexTrace(p
, "leave");
254 sqlite3_mutex_methods
const *sqlite3DefaultMutex(void){
255 static const sqlite3_mutex_methods sMutex
= {
274 #endif /* SQLITE_MUTEX_OS2 */