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