248 lines
No EOL
7 KiB
C#
248 lines
No EOL
7 KiB
C#
using System.Diagnostics;
|
|
|
|
namespace Community.CsharpSqlite
|
|
{
|
|
public partial class Sqlite3
|
|
{
|
|
/*
|
|
** 2008 October 07
|
|
**
|
|
** 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.
|
|
**
|
|
** This implementation in this file does not provide any mutual
|
|
** exclusion and is thus suitable for use only in applications
|
|
** that use SQLite in a single thread. The routines defined
|
|
** here are place-holders. Applications can substitute working
|
|
** mutex routines at start-time using the
|
|
**
|
|
** sqlite3_config(SQLITE_CONFIG_MUTEX,...)
|
|
**
|
|
** interface.
|
|
**
|
|
** If compiled with SQLITE_DEBUG, then additional logic is inserted
|
|
** that does error checking on mutexes to make sure they are being
|
|
** called correctly.
|
|
*************************************************************************
|
|
** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart
|
|
** C#-SQLite is an independent reimplementation of the SQLite software library
|
|
**
|
|
** SQLITE_SOURCE_ID: 2009-12-07 16:39:13 1ed88e9d01e9eda5cbc622e7614277f29bcc551c
|
|
**
|
|
*************************************************************************
|
|
*/
|
|
//#include "sqliteInt.h"
|
|
|
|
#if !SQLITE_DEBUG
|
|
/*
|
|
** Stub routines for all mutex methods.
|
|
**
|
|
** This routines provide no mutual exclusion or error checking.
|
|
*/
|
|
static int noopMutexHeld(sqlite3_mutex p){ return 1; }
|
|
static int noopMutexNotheld(sqlite3_mutex p){ return 1; }
|
|
static int noopMutexInit(){ return SQLITE_OK; }
|
|
static int noopMutexEnd(){ return SQLITE_OK; }
|
|
static sqlite3_mutex noopMutexAlloc(int id){ return new sqlite3_mutex(); }
|
|
static void noopMutexFree(sqlite3_mutex p){ }
|
|
static void noopMutexEnter(sqlite3_mutex p){ }
|
|
static int noopMutexTry(sqlite3_mutex p){ return SQLITE_OK; }
|
|
static void noopMutexLeave(sqlite3_mutex p){ }
|
|
|
|
sqlite3_mutex_methods sqlite3NoopMutex(){
|
|
sqlite3_mutex_methods sMutex = new sqlite3_mutex_methods(
|
|
(dxMutexInit)noopMutexInit,
|
|
(dxMutexEnd)noopMutexEnd,
|
|
(dxMutexAlloc)noopMutexAlloc,
|
|
(dxMutexFree)noopMutexFree,
|
|
(dxMutexEnter)noopMutexEnter,
|
|
(dxMutexTry)noopMutexTry,
|
|
(dxMutexLeave)noopMutexLeave,
|
|
#if SQLITE_DEBUG
|
|
(dxMutexHeld)noopMutexHeld,
|
|
(dxMutexNotheld)noopMutexNotheld
|
|
#else
|
|
null,
|
|
null
|
|
#endif
|
|
);
|
|
|
|
return sMutex;
|
|
}
|
|
#endif //* !SQLITE_DEBUG */
|
|
|
|
#if SQLITE_DEBUG && !SQLITE_MUTEX_OMIT
|
|
/*
|
|
** In this implementation, error checking is provided for testing
|
|
** and debugging purposes. The mutexes still do not provide any
|
|
** mutual exclusion.
|
|
*/
|
|
|
|
/*
|
|
** The mutex object
|
|
*/
|
|
|
|
public class sqlite3_debug_mutex : sqlite3_mutex
|
|
{
|
|
//public int id; /* The mutex type */
|
|
public int cnt; /* Number of entries without a matching leave */
|
|
};
|
|
|
|
/*
|
|
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
|
|
** intended for use inside Debug.Assert() statements.
|
|
*/
|
|
|
|
private static bool debugMutexHeld(sqlite3_mutex pX)
|
|
{
|
|
sqlite3_debug_mutex p = (sqlite3_debug_mutex)pX;
|
|
return p == null || p.cnt > 0;
|
|
}
|
|
|
|
private static bool debugMutexNotheld(sqlite3_mutex pX)
|
|
{
|
|
sqlite3_debug_mutex p = (sqlite3_debug_mutex)pX;
|
|
return p == null || p.cnt == 0;
|
|
}
|
|
|
|
/*
|
|
** Initialize and deinitialize the mutex subsystem.
|
|
*/
|
|
|
|
private static int debugMutexInit()
|
|
{
|
|
return SQLITE_OK;
|
|
}
|
|
|
|
private static int debugMutexEnd()
|
|
{
|
|
return SQLITE_OK;
|
|
}
|
|
|
|
/*
|
|
** 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.
|
|
*/
|
|
|
|
private static sqlite3_mutex debugMutexAlloc(int id)
|
|
{
|
|
sqlite3_debug_mutex[] aStatic = new sqlite3_debug_mutex[6];
|
|
sqlite3_debug_mutex pNew = null;
|
|
switch (id)
|
|
{
|
|
case SQLITE_MUTEX_FAST:
|
|
case SQLITE_MUTEX_RECURSIVE:
|
|
{
|
|
pNew = new sqlite3_debug_mutex();//sqlite3Malloc(sizeof(*pNew));
|
|
if (pNew != null)
|
|
{
|
|
pNew.id = id;
|
|
pNew.cnt = 0;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
Debug.Assert(id - 2 >= 0);
|
|
Debug.Assert(id - 2 < aStatic.Length);//(int)(sizeof(aStatic)/sizeof(aStatic[0])) );
|
|
pNew = aStatic[id - 2];
|
|
pNew.id = id;
|
|
break;
|
|
}
|
|
}
|
|
return pNew;
|
|
}
|
|
|
|
/*
|
|
** This routine deallocates a previously allocated mutex.
|
|
*/
|
|
|
|
private static void debugMutexFree(sqlite3_mutex pX)
|
|
{
|
|
sqlite3_debug_mutex p = (sqlite3_debug_mutex)pX;
|
|
Debug.Assert(p.cnt == 0);
|
|
Debug.Assert(p.id == SQLITE_MUTEX_FAST || p.id == SQLITE_MUTEX_RECURSIVE);
|
|
//sqlite3_free(ref 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.
|
|
*/
|
|
|
|
private static void debugMutexEnter(sqlite3_mutex pX)
|
|
{
|
|
sqlite3_debug_mutex p = (sqlite3_debug_mutex)pX;
|
|
Debug.Assert(p.id == SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(p));
|
|
p.cnt++;
|
|
}
|
|
|
|
private static int debugMutexTry(sqlite3_mutex pX)
|
|
{
|
|
sqlite3_debug_mutex p = (sqlite3_debug_mutex)pX;
|
|
Debug.Assert(p.id == SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(p));
|
|
p.cnt++;
|
|
return SQLITE_OK;
|
|
}
|
|
|
|
/*
|
|
** 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.
|
|
*/
|
|
|
|
private static void debugMutexLeave(sqlite3_mutex pX)
|
|
{
|
|
sqlite3_debug_mutex p = (sqlite3_debug_mutex)pX;
|
|
Debug.Assert(debugMutexHeld(p));
|
|
p.cnt--;
|
|
Debug.Assert(p.id == SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(p));
|
|
}
|
|
|
|
private static sqlite3_mutex_methods sqlite3NoopMutex()
|
|
{
|
|
sqlite3_mutex_methods sMutex = new sqlite3_mutex_methods(
|
|
(dxMutexInit)debugMutexInit,
|
|
(dxMutexEnd)debugMutexEnd,
|
|
(dxMutexAlloc)debugMutexAlloc,
|
|
(dxMutexFree)debugMutexFree,
|
|
(dxMutexEnter)debugMutexEnter,
|
|
(dxMutexTry)debugMutexTry,
|
|
(dxMutexLeave)debugMutexLeave,
|
|
|
|
(dxMutexHeld)debugMutexHeld,
|
|
(dxMutexNotheld)debugMutexNotheld
|
|
);
|
|
|
|
return sMutex;
|
|
}
|
|
|
|
#endif //* SQLITE_DEBUG */
|
|
|
|
/*
|
|
** If compiled with SQLITE_MUTEX_NOOP, then the no-op mutex implementation
|
|
** is used regardless of the run-time threadsafety setting.
|
|
*/
|
|
#if SQLITE_MUTEX_NOOP
|
|
sqlite3_mutex_methods const sqlite3DefaultMutex(void){
|
|
return sqlite3NoopMutex();
|
|
}
|
|
#endif //* SQLITE_MUTEX_NOOP */
|
|
}
|
|
} |