251cced1f8
Various minor things done to project files Updated sample extension project file and updated makefile to the new unified version (more changes likely on the way) Updated regex project file and makefile --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401971
209 lines
6.8 KiB
C
209 lines
6.8 KiB
C
/*
|
|
** 2007 August 14
|
|
**
|
|
** The author disclaims copyright to this source code. In place of
|
|
** a legal notice, here is a blessing:
|
|
**
|
|
** May you do good and not evil.
|
|
** May you find forgiveness for yourself and forgive others.
|
|
** May you share freely, never taking more than you give.
|
|
**
|
|
*************************************************************************
|
|
** This file contains the C functions that implement mutexes for win32
|
|
**
|
|
** $Id$
|
|
*/
|
|
#include "sqliteInt.h"
|
|
|
|
/*
|
|
** The code in this file is only used if we are compiling multithreaded
|
|
** on a win32 system.
|
|
*/
|
|
#ifdef SQLITE_MUTEX_W32
|
|
|
|
/*
|
|
** Each recursive mutex is an instance of the following structure.
|
|
*/
|
|
struct sqlite3_mutex {
|
|
CRITICAL_SECTION mutex; /* Mutex controlling the lock */
|
|
int id; /* Mutex type */
|
|
int nRef; /* Number of enterances */
|
|
DWORD owner; /* Thread holding this mutex */
|
|
};
|
|
|
|
/*
|
|
** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
|
|
** or WinCE. Return false (zero) for Win95, Win98, or WinME.
|
|
**
|
|
** Here is an interesting observation: Win95, Win98, and WinME lack
|
|
** the LockFileEx() API. But we can still statically link against that
|
|
** API as long as we don't call it win running Win95/98/ME. A call to
|
|
** this routine is used to determine if the host is Win95/98/ME or
|
|
** WinNT/2K/XP so that we will know whether or not we can safely call
|
|
** the LockFileEx() API.
|
|
*/
|
|
#if OS_WINCE
|
|
# define mutexIsNT() (1)
|
|
#else
|
|
static int mutexIsNT(void){
|
|
static int osType = 0;
|
|
if( osType==0 ){
|
|
OSVERSIONINFO sInfo;
|
|
sInfo.dwOSVersionInfoSize = sizeof(sInfo);
|
|
GetVersionEx(&sInfo);
|
|
osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
|
|
}
|
|
return osType==2;
|
|
}
|
|
#endif /* OS_WINCE */
|
|
|
|
|
|
/*
|
|
** The sqlite3_mutex_alloc() routine allocates a new
|
|
** mutex and returns a pointer to it. If it returns NULL
|
|
** that means that a mutex could not be allocated. SQLite
|
|
** will unwind its stack and return an error. The argument
|
|
** to sqlite3_mutex_alloc() is one of these integer constants:
|
|
**
|
|
** <ul>
|
|
** <li> SQLITE_MUTEX_FAST 0
|
|
** <li> SQLITE_MUTEX_RECURSIVE 1
|
|
** <li> SQLITE_MUTEX_STATIC_MASTER 2
|
|
** <li> SQLITE_MUTEX_STATIC_MEM 3
|
|
** <li> SQLITE_MUTEX_STATIC_PRNG 4
|
|
** </ul>
|
|
**
|
|
** The first two constants cause sqlite3_mutex_alloc() to create
|
|
** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
|
|
** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
|
|
** The mutex implementation does not need to make a distinction
|
|
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
|
|
** not want to. But SQLite will only request a recursive mutex in
|
|
** cases where it really needs one. If a faster non-recursive mutex
|
|
** implementation is available on the host platform, the mutex subsystem
|
|
** might return such a mutex in response to SQLITE_MUTEX_FAST.
|
|
**
|
|
** The other allowed parameters to sqlite3_mutex_alloc() each return
|
|
** a pointer to a static preexisting mutex. Three static mutexes are
|
|
** used by the current version of SQLite. Future versions of SQLite
|
|
** may add additional static mutexes. Static mutexes are for internal
|
|
** use by SQLite only. Applications that use SQLite mutexes should
|
|
** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
|
|
** SQLITE_MUTEX_RECURSIVE.
|
|
**
|
|
** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
|
|
** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
|
|
** returns a different mutex on every call. But for the static
|
|
** mutex types, the same mutex is returned on every call that has
|
|
** the same type number.
|
|
*/
|
|
sqlite3_mutex *sqlite3_mutex_alloc(int iType){
|
|
sqlite3_mutex *p;
|
|
|
|
switch( iType ){
|
|
case SQLITE_MUTEX_FAST:
|
|
case SQLITE_MUTEX_RECURSIVE: {
|
|
p = sqlite3MallocZero( sizeof(*p) );
|
|
if( p ){
|
|
p->id = iType;
|
|
InitializeCriticalSection(&p->mutex);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
static sqlite3_mutex staticMutexes[5];
|
|
static int isInit = 0;
|
|
while( !isInit ){
|
|
static long lock = 0;
|
|
if( InterlockedIncrement(&lock)==1 ){
|
|
int i;
|
|
for(i=0; i<sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++){
|
|
InitializeCriticalSection(&staticMutexes[i].mutex);
|
|
}
|
|
isInit = 1;
|
|
}else{
|
|
Sleep(1);
|
|
}
|
|
}
|
|
assert( iType-2 >= 0 );
|
|
assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) );
|
|
p = &staticMutexes[iType-2];
|
|
p->id = iType;
|
|
break;
|
|
}
|
|
}
|
|
return p;
|
|
}
|
|
|
|
|
|
/*
|
|
** This routine deallocates a previously
|
|
** allocated mutex. SQLite is careful to deallocate every
|
|
** mutex that it allocates.
|
|
*/
|
|
void sqlite3_mutex_free(sqlite3_mutex *p){
|
|
assert( p );
|
|
assert( p->nRef==0 );
|
|
assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
|
|
DeleteCriticalSection(&p->mutex);
|
|
sqlite3_free(p);
|
|
}
|
|
|
|
/*
|
|
** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
|
|
** to enter a mutex. If another thread is already within the mutex,
|
|
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
|
|
** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
|
|
** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
|
|
** be entered multiple times by the same thread. In such cases the,
|
|
** mutex must be exited an equal number of times before another thread
|
|
** can enter. If the same thread tries to enter any other kind of mutex
|
|
** more than once, the behavior is undefined.
|
|
*/
|
|
void sqlite3_mutex_enter(sqlite3_mutex *p){
|
|
assert( p );
|
|
assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
|
|
EnterCriticalSection(&p->mutex);
|
|
p->owner = GetCurrentThreadId();
|
|
p->nRef++;
|
|
}
|
|
int sqlite3_mutex_try(sqlite3_mutex *p){
|
|
int rc;
|
|
assert( p );
|
|
assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
|
|
if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){
|
|
p->owner = GetCurrentThreadId();
|
|
p->nRef++;
|
|
rc = SQLITE_OK;
|
|
}else{
|
|
rc = SQLITE_BUSY;
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
** The sqlite3_mutex_leave() routine exits a mutex that was
|
|
** previously entered by the same thread. The behavior
|
|
** is undefined if the mutex is not currently entered or
|
|
** is not currently allocated. SQLite will never do either.
|
|
*/
|
|
void sqlite3_mutex_leave(sqlite3_mutex *p){
|
|
assert( p->nRef>0 );
|
|
assert( p->owner==GetCurrentThreadId() );
|
|
p->nRef--;
|
|
assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
|
|
LeaveCriticalSection(&p->mutex);
|
|
}
|
|
|
|
/*
|
|
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
|
|
** intended for use only inside assert() statements.
|
|
*/
|
|
int sqlite3_mutex_held(sqlite3_mutex *p){
|
|
return p==0 || (p->nRef!=0 && p->owner==GetCurrentThreadId());
|
|
}
|
|
int sqlite3_mutex_notheld(sqlite3_mutex *p){
|
|
return p==0 || p->nRef==0 || p->owner!=GetCurrentThreadId();
|
|
}
|
|
#endif /* SQLITE_MUTEX_W32 */
|