OLD | NEW |
1 /* | 1 /* |
2 ** 2008 October 07 | 2 ** 2008 October 07 |
3 ** | 3 ** |
4 ** The author disclaims copyright to this source code. In place of | 4 ** The author disclaims copyright to this source code. In place of |
5 ** a legal notice, here is a blessing: | 5 ** a legal notice, here is a blessing: |
6 ** | 6 ** |
7 ** May you do good and not evil. | 7 ** May you do good and not evil. |
8 ** May you find forgiveness for yourself and forgive others. | 8 ** May you find forgiveness for yourself and forgive others. |
9 ** May you share freely, never taking more than you give. | 9 ** May you share freely, never taking more than you give. |
10 ** | 10 ** |
11 ************************************************************************* | 11 ************************************************************************* |
12 ** This file contains the C functions that implement mutexes. | 12 ** This file contains the C functions that implement mutexes. |
13 ** | 13 ** |
14 ** This implementation in this file does not provide any mutual | 14 ** This implementation in this file does not provide any mutual |
15 ** exclusion and is thus suitable for use only in applications | 15 ** exclusion and is thus suitable for use only in applications |
16 ** that use SQLite in a single thread. The routines defined | 16 ** that use SQLite in a single thread. The routines defined |
17 ** here are place-holders. Applications can substitute working | 17 ** here are place-holders. Applications can substitute working |
18 ** mutex routines at start-time using the | 18 ** mutex routines at start-time using the |
19 ** | 19 ** |
20 ** sqlite3_config(SQLITE_CONFIG_MUTEX,...) | 20 ** sqlite3_config(SQLITE_CONFIG_MUTEX,...) |
21 ** | 21 ** |
22 ** interface. | 22 ** interface. |
23 ** | 23 ** |
24 ** If compiled with SQLITE_DEBUG, then additional logic is inserted | 24 ** If compiled with SQLITE_DEBUG, then additional logic is inserted |
25 ** that does error checking on mutexes to make sure they are being | 25 ** that does error checking on mutexes to make sure they are being |
26 ** called correctly. | 26 ** called correctly. |
27 ** | |
28 ** $Id: mutex_noop.c,v 1.3 2008/12/05 17:17:08 drh Exp $ | |
29 */ | 27 */ |
30 #include "sqliteInt.h" | 28 #include "sqliteInt.h" |
31 | 29 |
| 30 #ifndef SQLITE_MUTEX_OMIT |
32 | 31 |
33 #if defined(SQLITE_MUTEX_NOOP) && !defined(SQLITE_DEBUG) | 32 #ifndef SQLITE_DEBUG |
34 /* | 33 /* |
35 ** Stub routines for all mutex methods. | 34 ** Stub routines for all mutex methods. |
36 ** | 35 ** |
37 ** This routines provide no mutual exclusion or error checking. | 36 ** This routines provide no mutual exclusion or error checking. |
38 */ | 37 */ |
39 static int noopMutexHeld(sqlite3_mutex *p){ return 1; } | |
40 static int noopMutexNotheld(sqlite3_mutex *p){ return 1; } | |
41 static int noopMutexInit(void){ return SQLITE_OK; } | 38 static int noopMutexInit(void){ return SQLITE_OK; } |
42 static int noopMutexEnd(void){ return SQLITE_OK; } | 39 static int noopMutexEnd(void){ return SQLITE_OK; } |
43 static sqlite3_mutex *noopMutexAlloc(int id){ return (sqlite3_mutex*)8; } | 40 static sqlite3_mutex *noopMutexAlloc(int id){ |
44 static void noopMutexFree(sqlite3_mutex *p){ return; } | 41 UNUSED_PARAMETER(id); |
45 static void noopMutexEnter(sqlite3_mutex *p){ return; } | 42 return (sqlite3_mutex*)8; |
46 static int noopMutexTry(sqlite3_mutex *p){ return SQLITE_OK; } | 43 } |
47 static void noopMutexLeave(sqlite3_mutex *p){ return; } | 44 static void noopMutexFree(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } |
| 45 static void noopMutexEnter(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } |
| 46 static int noopMutexTry(sqlite3_mutex *p){ |
| 47 UNUSED_PARAMETER(p); |
| 48 return SQLITE_OK; |
| 49 } |
| 50 static void noopMutexLeave(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } |
48 | 51 |
49 sqlite3_mutex_methods *sqlite3DefaultMutex(void){ | 52 sqlite3_mutex_methods const *sqlite3NoopMutex(void){ |
50 static sqlite3_mutex_methods sMutex = { | 53 static const sqlite3_mutex_methods sMutex = { |
51 noopMutexInit, | 54 noopMutexInit, |
52 noopMutexEnd, | 55 noopMutexEnd, |
53 noopMutexAlloc, | 56 noopMutexAlloc, |
54 noopMutexFree, | 57 noopMutexFree, |
55 noopMutexEnter, | 58 noopMutexEnter, |
56 noopMutexTry, | 59 noopMutexTry, |
57 noopMutexLeave, | 60 noopMutexLeave, |
58 | 61 |
59 noopMutexHeld, | 62 0, |
60 noopMutexNotheld | 63 0, |
61 }; | 64 }; |
62 | 65 |
63 return &sMutex; | 66 return &sMutex; |
64 } | 67 } |
65 #endif /* defined(SQLITE_MUTEX_NOOP) && !defined(SQLITE_DEBUG) */ | 68 #endif /* !SQLITE_DEBUG */ |
66 | 69 |
67 #if defined(SQLITE_MUTEX_NOOP) && defined(SQLITE_DEBUG) | 70 #ifdef SQLITE_DEBUG |
68 /* | 71 /* |
69 ** In this implementation, error checking is provided for testing | 72 ** In this implementation, error checking is provided for testing |
70 ** and debugging purposes. The mutexes still do not provide any | 73 ** and debugging purposes. The mutexes still do not provide any |
71 ** mutual exclusion. | 74 ** mutual exclusion. |
72 */ | 75 */ |
73 | 76 |
74 /* | 77 /* |
75 ** The mutex object | 78 ** The mutex object |
76 */ | 79 */ |
77 struct sqlite3_mutex { | 80 typedef struct sqlite3_debug_mutex { |
78 int id; /* The mutex type */ | 81 int id; /* The mutex type */ |
79 int cnt; /* Number of entries without a matching leave */ | 82 int cnt; /* Number of entries without a matching leave */ |
80 }; | 83 } sqlite3_debug_mutex; |
81 | 84 |
82 /* | 85 /* |
83 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are | 86 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are |
84 ** intended for use inside assert() statements. | 87 ** intended for use inside assert() statements. |
85 */ | 88 */ |
86 static int debugMutexHeld(sqlite3_mutex *p){ | 89 static int debugMutexHeld(sqlite3_mutex *pX){ |
| 90 sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; |
87 return p==0 || p->cnt>0; | 91 return p==0 || p->cnt>0; |
88 } | 92 } |
89 static int debugMutexNotheld(sqlite3_mutex *p){ | 93 static int debugMutexNotheld(sqlite3_mutex *pX){ |
| 94 sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; |
90 return p==0 || p->cnt==0; | 95 return p==0 || p->cnt==0; |
91 } | 96 } |
92 | 97 |
93 /* | 98 /* |
94 ** Initialize and deinitialize the mutex subsystem. | 99 ** Initialize and deinitialize the mutex subsystem. |
95 */ | 100 */ |
96 static int debugMutexInit(void){ return SQLITE_OK; } | 101 static int debugMutexInit(void){ return SQLITE_OK; } |
97 static int debugMutexEnd(void){ return SQLITE_OK; } | 102 static int debugMutexEnd(void){ return SQLITE_OK; } |
98 | 103 |
99 /* | 104 /* |
100 ** The sqlite3_mutex_alloc() routine allocates a new | 105 ** The sqlite3_mutex_alloc() routine allocates a new |
101 ** mutex and returns a pointer to it. If it returns NULL | 106 ** mutex and returns a pointer to it. If it returns NULL |
102 ** that means that a mutex could not be allocated. | 107 ** that means that a mutex could not be allocated. |
103 */ | 108 */ |
104 static sqlite3_mutex *debugMutexAlloc(int id){ | 109 static sqlite3_mutex *debugMutexAlloc(int id){ |
105 static sqlite3_mutex aStatic[6]; | 110 static sqlite3_debug_mutex aStatic[6]; |
106 sqlite3_mutex *pNew = 0; | 111 sqlite3_debug_mutex *pNew = 0; |
107 switch( id ){ | 112 switch( id ){ |
108 case SQLITE_MUTEX_FAST: | 113 case SQLITE_MUTEX_FAST: |
109 case SQLITE_MUTEX_RECURSIVE: { | 114 case SQLITE_MUTEX_RECURSIVE: { |
110 pNew = sqlite3Malloc(sizeof(*pNew)); | 115 pNew = sqlite3Malloc(sizeof(*pNew)); |
111 if( pNew ){ | 116 if( pNew ){ |
112 pNew->id = id; | 117 pNew->id = id; |
113 pNew->cnt = 0; | 118 pNew->cnt = 0; |
114 } | 119 } |
115 break; | 120 break; |
116 } | 121 } |
117 default: { | 122 default: { |
118 assert( id-2 >= 0 ); | 123 assert( id-2 >= 0 ); |
119 assert( id-2 < (int)(sizeof(aStatic)/sizeof(aStatic[0])) ); | 124 assert( id-2 < (int)(sizeof(aStatic)/sizeof(aStatic[0])) ); |
120 pNew = &aStatic[id-2]; | 125 pNew = &aStatic[id-2]; |
121 pNew->id = id; | 126 pNew->id = id; |
122 break; | 127 break; |
123 } | 128 } |
124 } | 129 } |
125 return pNew; | 130 return (sqlite3_mutex*)pNew; |
126 } | 131 } |
127 | 132 |
128 /* | 133 /* |
129 ** This routine deallocates a previously allocated mutex. | 134 ** This routine deallocates a previously allocated mutex. |
130 */ | 135 */ |
131 static void debugMutexFree(sqlite3_mutex *p){ | 136 static void debugMutexFree(sqlite3_mutex *pX){ |
| 137 sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; |
132 assert( p->cnt==0 ); | 138 assert( p->cnt==0 ); |
133 assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); | 139 assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); |
134 sqlite3_free(p); | 140 sqlite3_free(p); |
135 } | 141 } |
136 | 142 |
137 /* | 143 /* |
138 ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt | 144 ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt |
139 ** to enter a mutex. If another thread is already within the mutex, | 145 ** to enter a mutex. If another thread is already within the mutex, |
140 ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return | 146 ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return |
141 ** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK | 147 ** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK |
142 ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can | 148 ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can |
143 ** be entered multiple times by the same thread. In such cases the, | 149 ** be entered multiple times by the same thread. In such cases the, |
144 ** mutex must be exited an equal number of times before another thread | 150 ** mutex must be exited an equal number of times before another thread |
145 ** can enter. If the same thread tries to enter any other kind of mutex | 151 ** can enter. If the same thread tries to enter any other kind of mutex |
146 ** more than once, the behavior is undefined. | 152 ** more than once, the behavior is undefined. |
147 */ | 153 */ |
148 static void debugMutexEnter(sqlite3_mutex *p){ | 154 static void debugMutexEnter(sqlite3_mutex *pX){ |
149 assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(p) ); | 155 sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; |
| 156 assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); |
150 p->cnt++; | 157 p->cnt++; |
151 } | 158 } |
152 static int debugMutexTry(sqlite3_mutex *p){ | 159 static int debugMutexTry(sqlite3_mutex *pX){ |
153 assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(p) ); | 160 sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; |
| 161 assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); |
154 p->cnt++; | 162 p->cnt++; |
155 return SQLITE_OK; | 163 return SQLITE_OK; |
156 } | 164 } |
157 | 165 |
158 /* | 166 /* |
159 ** The sqlite3_mutex_leave() routine exits a mutex that was | 167 ** The sqlite3_mutex_leave() routine exits a mutex that was |
160 ** previously entered by the same thread. The behavior | 168 ** previously entered by the same thread. The behavior |
161 ** is undefined if the mutex is not currently entered or | 169 ** is undefined if the mutex is not currently entered or |
162 ** is not currently allocated. SQLite will never do either. | 170 ** is not currently allocated. SQLite will never do either. |
163 */ | 171 */ |
164 static void debugMutexLeave(sqlite3_mutex *p){ | 172 static void debugMutexLeave(sqlite3_mutex *pX){ |
165 assert( debugMutexHeld(p) ); | 173 sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; |
| 174 assert( debugMutexHeld(pX) ); |
166 p->cnt--; | 175 p->cnt--; |
167 assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(p) ); | 176 assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); |
168 } | 177 } |
169 | 178 |
170 sqlite3_mutex_methods *sqlite3DefaultMutex(void){ | 179 sqlite3_mutex_methods const *sqlite3NoopMutex(void){ |
171 static sqlite3_mutex_methods sMutex = { | 180 static const sqlite3_mutex_methods sMutex = { |
172 debugMutexInit, | 181 debugMutexInit, |
173 debugMutexEnd, | 182 debugMutexEnd, |
174 debugMutexAlloc, | 183 debugMutexAlloc, |
175 debugMutexFree, | 184 debugMutexFree, |
176 debugMutexEnter, | 185 debugMutexEnter, |
177 debugMutexTry, | 186 debugMutexTry, |
178 debugMutexLeave, | 187 debugMutexLeave, |
179 | 188 |
180 debugMutexHeld, | 189 debugMutexHeld, |
181 debugMutexNotheld | 190 debugMutexNotheld |
182 }; | 191 }; |
183 | 192 |
184 return &sMutex; | 193 return &sMutex; |
185 } | 194 } |
186 #endif /* defined(SQLITE_MUTEX_NOOP) && defined(SQLITE_DEBUG) */ | 195 #endif /* SQLITE_DEBUG */ |
| 196 |
| 197 /* |
| 198 ** If compiled with SQLITE_MUTEX_NOOP, then the no-op mutex implementation |
| 199 ** is used regardless of the run-time threadsafety setting. |
| 200 */ |
| 201 #ifdef SQLITE_MUTEX_NOOP |
| 202 sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ |
| 203 return sqlite3NoopMutex(); |
| 204 } |
| 205 #endif /* SQLITE_MUTEX_NOOP */ |
| 206 #endif /* SQLITE_MUTEX_OMIT */ |
OLD | NEW |