1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-15 11:41:13 +03:00

Add the sqlite3_os_routine_set()/get() functions. (CVS 2818)

FossilOrigin-Name: c1ed79f594fb85009c2e9e5e281cbe66a9d2fa17
This commit is contained in:
danielk1977
2005-12-15 10:11:30 +00:00
parent af9a7c22b5
commit 13a68c3f61
14 changed files with 198 additions and 45 deletions

View File

@@ -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();
}

View File

@@ -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
*/

View File

@@ -1586,6 +1586,66 @@ static void unixLeaveMutex(){
#endif
}
/*
** 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
};

View File

@@ -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 */

View File

@@ -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.

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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;
}
/*