blob: 7c13244dbde9cb03177a7cab00ab0adfb074ab4d [file] [log] [blame]
drh18472fa2008-10-07 15:25:48 +00001/*
2** 2008 October 07
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.
13**
14** This implementation in this file does not provide any mutual
15** exclusion and is thus suitable for use only in applications
16** that use SQLite in a single thread. The routines defined
17** here are place-holders. Applications can substitute working
18** mutex routines at start-time using the
19**
20** sqlite3_config(SQLITE_CONFIG_MUTEX,...)
21**
22** interface.
23**
24** If compiled with SQLITE_DEBUG, then additional logic is inserted
25** that does error checking on mutexes to make sure they are being
26** called correctly.
27**
drh902b9ee2008-12-05 17:17:07 +000028** $Id: mutex_noop.c,v 1.3 2008/12/05 17:17:08 drh Exp $
drh18472fa2008-10-07 15:25:48 +000029*/
30#include "sqliteInt.h"
31
32
33#if defined(SQLITE_MUTEX_NOOP) && !defined(SQLITE_DEBUG)
34/*
35** Stub routines for all mutex methods.
36**
37** This routines provide no mutual exclusion or error checking.
38*/
39static int noopMutexHeld(sqlite3_mutex *p){ return 1; }
40static int noopMutexNotheld(sqlite3_mutex *p){ return 1; }
41static int noopMutexInit(void){ return SQLITE_OK; }
42static int noopMutexEnd(void){ return SQLITE_OK; }
43static sqlite3_mutex *noopMutexAlloc(int id){ return (sqlite3_mutex*)8; }
44static void noopMutexFree(sqlite3_mutex *p){ return; }
45static void noopMutexEnter(sqlite3_mutex *p){ return; }
46static int noopMutexTry(sqlite3_mutex *p){ return SQLITE_OK; }
drh9e885cd2008-10-15 19:03:02 +000047static void noopMutexLeave(sqlite3_mutex *p){ return; }
drh18472fa2008-10-07 15:25:48 +000048
49sqlite3_mutex_methods *sqlite3DefaultMutex(void){
50 static sqlite3_mutex_methods sMutex = {
51 noopMutexInit,
52 noopMutexEnd,
53 noopMutexAlloc,
54 noopMutexFree,
55 noopMutexEnter,
56 noopMutexTry,
57 noopMutexLeave,
58
59 noopMutexHeld,
60 noopMutexNotheld
61 };
62
63 return &sMutex;
64}
65#endif /* defined(SQLITE_MUTEX_NOOP) && !defined(SQLITE_DEBUG) */
66
67#if defined(SQLITE_MUTEX_NOOP) && defined(SQLITE_DEBUG)
68/*
69** In this implementation, error checking is provided for testing
70** and debugging purposes. The mutexes still do not provide any
71** mutual exclusion.
72*/
73
74/*
75** The mutex object
76*/
77struct sqlite3_mutex {
78 int id; /* The mutex type */
79 int cnt; /* Number of entries without a matching leave */
80};
81
82/*
83** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
84** intended for use inside assert() statements.
85*/
86static int debugMutexHeld(sqlite3_mutex *p){
87 return p==0 || p->cnt>0;
88}
89static int debugMutexNotheld(sqlite3_mutex *p){
90 return p==0 || p->cnt==0;
91}
92
93/*
94** Initialize and deinitialize the mutex subsystem.
95*/
96static int debugMutexInit(void){ return SQLITE_OK; }
97static int debugMutexEnd(void){ return SQLITE_OK; }
98
99/*
100** The sqlite3_mutex_alloc() routine allocates a new
101** mutex and returns a pointer to it. If it returns NULL
102** that means that a mutex could not be allocated.
103*/
104static sqlite3_mutex *debugMutexAlloc(int id){
105 static sqlite3_mutex aStatic[6];
106 sqlite3_mutex *pNew = 0;
107 switch( id ){
108 case SQLITE_MUTEX_FAST:
109 case SQLITE_MUTEX_RECURSIVE: {
110 pNew = sqlite3Malloc(sizeof(*pNew));
111 if( pNew ){
112 pNew->id = id;
113 pNew->cnt = 0;
114 }
115 break;
116 }
117 default: {
118 assert( id-2 >= 0 );
drh902b9ee2008-12-05 17:17:07 +0000119 assert( id-2 < (int)(sizeof(aStatic)/sizeof(aStatic[0])) );
drh18472fa2008-10-07 15:25:48 +0000120 pNew = &aStatic[id-2];
121 pNew->id = id;
122 break;
123 }
124 }
125 return pNew;
126}
127
128/*
129** This routine deallocates a previously allocated mutex.
130*/
131static void debugMutexFree(sqlite3_mutex *p){
132 assert( p->cnt==0 );
133 assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
134 sqlite3_free(p);
135}
136
137/*
138** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
139** to enter a mutex. If another thread is already within the mutex,
140** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
141** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
142** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
143** 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
145** can enter. If the same thread tries to enter any other kind of mutex
146** more than once, the behavior is undefined.
147*/
148static void debugMutexEnter(sqlite3_mutex *p){
149 assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(p) );
150 p->cnt++;
151}
152static int debugMutexTry(sqlite3_mutex *p){
153 assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(p) );
154 p->cnt++;
155 return SQLITE_OK;
156}
157
158/*
159** The sqlite3_mutex_leave() routine exits a mutex that was
160** previously entered by the same thread. The behavior
161** is undefined if the mutex is not currently entered or
162** is not currently allocated. SQLite will never do either.
163*/
164static void debugMutexLeave(sqlite3_mutex *p){
165 assert( debugMutexHeld(p) );
166 p->cnt--;
167 assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(p) );
168}
169
170sqlite3_mutex_methods *sqlite3DefaultMutex(void){
171 static sqlite3_mutex_methods sMutex = {
172 debugMutexInit,
173 debugMutexEnd,
174 debugMutexAlloc,
175 debugMutexFree,
176 debugMutexEnter,
177 debugMutexTry,
178 debugMutexLeave,
179
180 debugMutexHeld,
181 debugMutexNotheld
182 };
183
184 return &sMutex;
185}
186#endif /* defined(SQLITE_MUTEX_NOOP) && defined(SQLITE_DEBUG) */