aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordanielk1977 <danielk1977@noemail.net>2005-12-15 10:11:30 +0000
committerdanielk1977 <danielk1977@noemail.net>2005-12-15 10:11:30 +0000
commit13a68c3f61385c5e05e73d976127c1108fd624bb (patch)
treedf063d568da0e892d332d7c02b3090616719c2e7 /src
parentaf9a7c22b5b25d557eab2f7e1a66a65fde78005d (diff)
downloadsqlite-13a68c3f61385c5e05e73d976127c1108fd624bb.tar.gz
sqlite-13a68c3f61385c5e05e73d976127c1108fd624bb.zip
Add the sqlite3_os_routine_set()/get() functions. (CVS 2818)
FossilOrigin-Name: c1ed79f594fb85009c2e9e5e281cbe66a9d2fa17
Diffstat (limited to 'src')
-rw-r--r--src/os.c39
-rw-r--r--src/os.h22
-rw-r--r--src/os_unix.c61
-rw-r--r--src/os_win.c16
-rw-r--r--src/sqlite.h.in6
-rw-r--r--src/sqliteInt.h3
-rw-r--r--src/tclsqlite.c4
-rw-r--r--src/util.c43
8 files changed, 171 insertions, 23 deletions
diff --git a/src/os.c b/src/os.c
index 97036746a..a1acd7671 100644
--- a/src/os.c
+++ b/src/os.c
@@ -69,3 +69,42 @@ int sqlite3OsLockState(OsFile *id){
int sqlite3OsCheckReservedLock(OsFile *id){
return id->pMethod->xCheckReservedLock(id);
}
+
+static void**getOsRoutinePtr(int eRoutine){
+ switch( eRoutine ){
+ case SQLITE_OS_ROUTINE_OPENREADWRITE:
+ return (void **)(&sqlite3Os.xOpenReadWrite);
+ case SQLITE_OS_ROUTINE_OPENREADONLY:
+ return (void **)(&sqlite3Os.xOpenReadOnly);
+ case SQLITE_OS_ROUTINE_OPENEXCLUSIVE:
+ return (void **)(&sqlite3Os.xOpenExclusive);
+ case SQLITE_OS_ROUTINE_DELETE:
+ return (void **)(&sqlite3Os.xDelete);
+ case SQLITE_OS_ROUTINE_FILEEXISTS:
+ return (void **)(&sqlite3Os.xFileExists);
+ case SQLITE_OS_ROUTINE_SYNCDIRECTORY:
+ return (void **)(&sqlite3Os.xSyncDirectory);
+ default:
+ assert(!"Illegal eRoutine value");
+ }
+ return 0;
+}
+
+void *sqlite3_os_routine_get(int eRoutine){
+ return *getOsRoutinePtr(eRoutine);
+}
+
+void *sqlite3_os_routine_set(int eRoutine, void *pRoutine){
+ void **ppRet = getOsRoutinePtr(eRoutine);
+ void *pRet = *ppRet;
+ *ppRet = pRoutine;
+ return pRet;
+}
+
+void sqlite3_os_enter_mutex(){
+ sqlite3Os.xEnterMutex();
+}
+void sqlite3_os_leave_mutex(){
+ sqlite3Os.xLeaveMutex();
+}
+
diff --git a/src/os.h b/src/os.h
index dc0e8d88c..739c8a95b 100644
--- a/src/os.h
+++ b/src/os.h
@@ -222,8 +222,30 @@ extern struct sqlite3OsVtbl {
int (*xCurrentTime)(double*);
void (*xEnterMutex)(void);
void (*xLeaveMutex)(void);
+ void *(*xThreadSpecificData)(int);
} sqlite3Os;
+
+/*
+** The semi-published API for setting and getting methods from the
+** global sqlite3OsVtbl structure. Neither sqlite3_os_routine_XXX() function
+** is intriniscally thread-safe.
+**
+** External get/set access is only provided to the routines identified
+** by the hash-defined SQLITE_OS_ROUTINE symbols.
+*/
+#define SQLITE_OS_ROUTINE_OPENREADWRITE 1
+#define SQLITE_OS_ROUTINE_OPENREADONLY 2
+#define SQLITE_OS_ROUTINE_OPENEXCLUSIVE 3
+#define SQLITE_OS_ROUTINE_DELETE 4
+#define SQLITE_OS_ROUTINE_FILEEXISTS 5
+#define SQLITE_OS_ROUTINE_SYNCDIRECTORY 6
+void *sqlite3_os_routine_get(int);
+void *sqlite3_os_routine_set(int, void *);
+
+void sqlite3_os_enter_mutex();
+void sqlite3_os_leave_mutex();
+
/*
** Prototypes for routines found in os.c
*/
diff --git a/src/os_unix.c b/src/os_unix.c
index 349db3d7c..a7f1271ac 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -1587,6 +1587,66 @@ static void unixLeaveMutex(){
}
/*
+** This function is called automatically when a thread exists to delete
+** the threads SqliteTsd structure.
+**
+** Because the SqliteTsd structure is required by higher level routines
+** such as sqliteMalloc() we use OsFree() and OsMalloc() directly to
+** allocate the thread specific data.
+*/
+static void deleteTsd(void *pTsd){
+ sqlite3OsFree(pTsd);
+}
+
+/*
+** The first time this function is called from a specific thread, nByte
+** bytes of data area are allocated and zeroed. A pointer to the new
+** allocation is returned to the caller.
+**
+** Each subsequent call to this function from the thread returns the same
+** pointer. The argument is ignored in this case.
+*/
+static void *unixThreadSpecificData(int nByte){
+#ifdef SQLITE_UNIX_THREADS
+ static pthread_key_t key;
+ static int keyInit = 0;
+ void *pTsd;
+
+ if( !keyInit ){
+ sqlite3Os.xEnterMutex();
+ if( !keyInit ){
+ int rc;
+ rc = pthread_key_create(&key, deleteTsd);
+ if( rc ){
+ return 0;
+ }
+ keyInit = 1;
+ }
+ sqlite3Os.xLeaveMutex();
+ }
+
+ pTsd = (SqliteTsd *)pthread_getspecific(key);
+ if( !pTsd ){
+ pTsd = sqlite3OsMalloc(sizeof(SqliteTsd));
+ if( pTsd ){
+ memset(pTsd, 0, sizeof(SqliteTsd));
+ pthread_setspecific(key, pTsd);
+ }
+ }
+ return pTsd;
+#else
+ static char tsd[sizeof(SqliteTsd)];
+ static isInit = 0;
+ assert( nByte==sizeof(SqliteTsd) );
+ if( !isInit ){
+ memset(tsd, 0, sizeof(SqliteTsd));
+ isInit = 1;
+ }
+ return (void *)tsd;
+#endif
+}
+
+/*
** The following variable, if set to a non-zero value, becomes the result
** returned from sqlite3Os.xCurrentTime(). This is used for testing.
*/
@@ -1644,6 +1704,7 @@ struct sqlite3OsVtbl sqlite3Os = {
unixCurrentTime,
unixEnterMutex,
unixLeaveMutex,
+ unixThreadSpecificData
};
diff --git a/src/os_win.c b/src/os_win.c
index be561b75f..bfa0af033 100644
--- a/src/os_win.c
+++ b/src/os_win.c
@@ -1020,6 +1020,21 @@ static int winCurrentTime(double *prNow){
return 0;
}
+
+/*
+** Todo: This is a place-holder only
+*/
+static void *winThreadSpecificData(int nByte){
+ static char tsd[sizeof(SqliteTsd)];
+ static isInit = 0;
+ assert( nByte==sizeof(SqliteTsd) );
+ if( !isInit ){
+ memset(tsd, 0, sizeof(SqliteTsd));
+ isInit = 1;
+ }
+ return (void *)tsd;
+}
+
/* Macro used to comment out routines that do not exists when there is
** no disk I/O
*/
@@ -1047,6 +1062,7 @@ struct sqlite3OsVtbl sqlite3Os = {
winCurrentTime,
winEnterMutex,
winLeaveMutex,
+ winThreadSpecificData
};
#endif /* OS_WIN */
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 8c9e95a50..27551e533 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -12,7 +12,7 @@
** This header file defines the interface that the SQLite library
** presents to client programs.
**
-** @(#) $Id: sqlite.h.in,v 1.144 2005/12/12 06:53:05 danielk1977 Exp $
+** @(#) $Id: sqlite.h.in,v 1.145 2005/12/15 10:11:32 danielk1977 Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
@@ -1291,6 +1291,10 @@ sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
*/
void sqlite3_soft_heap_limit(int);
+
+int sqlite3_set_io_routine(int, void *);
+void *sqlite3_get_io_routine(int);
+
/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index aa1bf3e26..daf146da0 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.435 2005/12/15 03:04:11 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.436 2005/12/15 10:11:32 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -268,6 +268,7 @@ extern int sqlite3_iMallocReset; /* Set iMallocFail to this when it reaches 0 */
*/
typedef struct SqliteTsd SqliteTsd;
struct SqliteTsd {
+ int isInit; /* True if structure has been initialised */
int mallocFailed; /* True after a malloc() has failed */
#ifndef SQLITE_OMIT_SOFTHEAPLIMIT
unsigned int nSoftHeapLimit; /* (uint)-1 for unlimited */
diff --git a/src/tclsqlite.c b/src/tclsqlite.c
index 3b58df75c..af6c9101a 100644
--- a/src/tclsqlite.c
+++ b/src/tclsqlite.c
@@ -11,7 +11,7 @@
*************************************************************************
** A TCL Interface to SQLite
**
-** $Id: tclsqlite.c,v 1.137 2005/12/12 06:53:05 danielk1977 Exp $
+** $Id: tclsqlite.c,v 1.138 2005/12/15 10:11:32 danielk1977 Exp $
*/
#ifndef NO_TCL /* Omit this whole file if TCL is unavailable */
@@ -2092,6 +2092,7 @@ int TCLSH_MAIN(int argc, char **argv){
extern int Sqlitetest4_Init(Tcl_Interp*);
extern int Sqlitetest5_Init(Tcl_Interp*);
extern int Sqlitetest6_Init(Tcl_Interp*);
+ extern int Sqlitetestasync_Init(Tcl_Interp*);
extern int Md5_Init(Tcl_Interp*);
extern int Sqlitetestsse_Init(Tcl_Interp*);
@@ -2101,6 +2102,7 @@ int TCLSH_MAIN(int argc, char **argv){
Sqlitetest4_Init(interp);
Sqlitetest5_Init(interp);
Sqlitetest6_Init(interp);
+ Sqlitetestasync_Init(interp);
Md5_Init(interp);
#ifdef SQLITE_SSE
Sqlitetestsse_Init(interp);
diff --git a/src/util.c b/src/util.c
index 49b2c76df..b91339f65 100644
--- a/src/util.c
+++ b/src/util.c
@@ -14,9 +14,10 @@
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
-** $Id: util.c,v 1.152 2005/12/12 06:53:05 danielk1977 Exp $
+** $Id: util.c,v 1.153 2005/12/15 10:11:32 danielk1977 Exp $
*/
#include "sqliteInt.h"
+#include "os.h"
#include <stdarg.h>
#include <ctype.h>
@@ -107,6 +108,10 @@ int sqlite3OsAllocationSize(void *p){
** Begin code for memory allocation system test layer.
**
** Memory debugging is turned on by defining the SQLITE_MEMDEBUG macro.
+**
+** SQLITE_MEMDEBUG==1 -> Fence-posting only (thread safe)
+** SQLITE_MEMDEBUG==2 -> Fence-posting + linked list of allocations (not ts)
+** SQLITE_MEMDEBUG==3 -> Above + backtraces (not thread safe, req. glibc)
*/
/* Figure out whether or not to store backtrace() information for each malloc.
@@ -114,7 +119,7 @@ int sqlite3OsAllocationSize(void *p){
** greater and glibc is in use. If we don't want to use backtrace(), then just
** define it as an empty macro and set the amount of space reserved to 0.
*/
-#if defined(__GLIBC__) && SQLITE_MEMDEBUG>1
+#if defined(__GLIBC__) && SQLITE_MEMDEBUG>2
extern int backtrace(void **, int);
#define TESTALLOC_STACKSIZE 128
#define TESTALLOC_STACKFRAMES ((TESTALLOC_STACKSIZE-8)/sizeof(void*))
@@ -302,6 +307,8 @@ static void *getOsPointer(void *p)
return (void *)(&z[-1 * TESTALLOC_OFFSET_DATA(p)]);
}
+
+#if SQLITE_MEMDEBUG>1
/*
** The argument points to an Os level allocation. Link it into the threads list
** of allocations.
@@ -363,6 +370,11 @@ static void relinkAlloc(void *p)
((void **)(pp[1]))[0] = p;
}
}
+#else
+#define linkAlloc(x)
+#define relinkAlloc(x)
+#define unlinkAlloc(x)
+#endif
/*
** This function sets the result of the Tcl interpreter passed as an argument
@@ -1248,26 +1260,17 @@ void *sqlite3TextToPtr(const char *z){
/*
** Return a pointer to the SqliteTsd associated with the calling thread.
-** TODO: Actually return thread-specific-data instead of this global pointer.
*/
SqliteTsd *sqlite3Tsd(){
- static SqliteTsd tsd = {
- 0 /* mallocFailed flag */
- #ifndef SQLITE_OMIT_SOFTHEAPLIMIT
- , 0xFFFFFFFF /* nSoftHeapLimit */
- , 0 /* nAlloc */
- #endif
- #ifndef NDEBUG
- , 1 /* mallocAllowed flag */
- #endif
- #ifdef SQLITE_MEMDEBUG
- , 0
- , 0
- , 0
- , 0
- #endif
- };
- return &tsd;
+ SqliteTsd *pTsd = sqlite3Os.xThreadSpecificData(sizeof(SqliteTsd));
+ if( pTsd && !pTsd->isInit ){
+ pTsd->nSoftHeapLimit = 0xFFFFFFFF;
+#ifndef NDEBUG
+ pTsd->mallocAllowed = 1;
+#endif
+ pTsd->isInit = 1;
+ }
+ return pTsd;
}
/*