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