1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-10-27 08:52:26 +03:00

Change the OS interface layer to use traditional direct function call

implementations instead of the more complicated virtual function table.
Omit the asynchronous I/O demo. (CVS 2870)

FossilOrigin-Name: 2529c2e11fa1d345ec61f647e4f6fae20a7133d6
This commit is contained in:
drh
2006-01-06 14:32:19 +00:00
parent c87d34d05d
commit 66560adab3
29 changed files with 357 additions and 1360 deletions

View File

@@ -15,6 +15,7 @@
#include "sqliteInt.h"
#include "os.h"
#if OS_UNIX /* This file is used on unix only */
/*
** These #defines should enable >2GB file support on Posix if the
** underlying operating system supports it. If the OS lacks
@@ -88,6 +89,22 @@ struct unixFile {
#endif
};
/*
** Provide the ability to override some OS-layer functions during
** testing. This is used to simulate OS crashes to verify that
** commits are atomic even in the event of an OS crash.
*/
#ifdef SQLITE_CRASH_TEST
extern int sqlite3CrashTestEnable;
extern int sqlite3CrashOpenReadWrite(const char*, OsFile**, int*);
extern int sqlite3CrashOpenExclusive(const char*, OsFile**, int);
extern int sqlite3CrashOpenReadOnly(const char*, OsFile**, int);
# define CRASH_TEST_OVERRIDE(X,A,B,C) \
if(sqlite3CrashTestEnable){ return X(A,B,C); }
#else
# define CRASH_TEST_OVERRIDE(X,A,B,C) /* no-op */
#endif
/*
** Do not include any of the File I/O interface procedures if the
@@ -564,7 +581,7 @@ exit_findlockinfo:
/*
** Delete the named file
*/
static int unixDelete(const char *zFilename){
int sqlite3UnixDelete(const char *zFilename){
unlink(zFilename);
return SQLITE_OK;
}
@@ -572,7 +589,7 @@ static int unixDelete(const char *zFilename){
/*
** Return TRUE if the named file exists.
*/
static int unixFileExists(const char *zFilename){
int sqlite3UnixFileExists(const char *zFilename){
return access(zFilename, 0)==0;
}
@@ -592,7 +609,7 @@ static int allocateUnixFile(unixFile *pInit, OsFile **pId);
** On failure, the function returns SQLITE_CANTOPEN and leaves
** *id and *pReadonly unchanged.
*/
static int unixOpenReadWrite(
int sqlite3UnixOpenReadWrite(
const char *zFilename,
OsFile **pId,
int *pReadonly
@@ -600,6 +617,7 @@ static int unixOpenReadWrite(
int rc;
unixFile f;
CRASH_TEST_OVERRIDE(sqlite3CrashOpenReadWrite, zFilename, pId, pReadonly);
assert( 0==*pId );
f.dirfd = -1;
SET_THREADID(&f);
@@ -619,9 +637,9 @@ static int unixOpenReadWrite(
}else{
*pReadonly = 0;
}
sqlite3Os.xEnterMutex();
sqlite3OsEnterMutex();
rc = findLockInfo(f.h, &f.pLock, &f.pOpen);
sqlite3Os.xLeaveMutex();
sqlite3OsLeaveMutex();
if( rc ){
close(f.h);
return SQLITE_NOMEM;
@@ -646,10 +664,11 @@ static int unixOpenReadWrite(
**
** On failure, return SQLITE_CANTOPEN.
*/
static int unixOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
int sqlite3UnixOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
int rc;
unixFile f;
CRASH_TEST_OVERRIDE(sqlite3CrashOpenExclusive, zFilename, pId, delFlag);
assert( 0==*pId );
if( access(zFilename, 0)==0 ){
return SQLITE_CANTOPEN;
@@ -662,9 +681,9 @@ static int unixOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
if( f.h<0 ){
return SQLITE_CANTOPEN;
}
sqlite3Os.xEnterMutex();
sqlite3OsEnterMutex();
rc = findLockInfo(f.h, &f.pLock, &f.pOpen);
sqlite3Os.xLeaveMutex();
sqlite3OsLeaveMutex();
if( rc ){
close(f.h);
unlink(zFilename);
@@ -685,10 +704,11 @@ static int unixOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
**
** On failure, return SQLITE_CANTOPEN.
*/
static int unixOpenReadOnly(const char *zFilename, OsFile **pId){
int sqlite3UnixOpenReadOnly(const char *zFilename, OsFile **pId){
int rc;
unixFile f;
CRASH_TEST_OVERRIDE(sqlite3CrashOpenReadOnly, zFilename, pId, 0);
assert( 0==*pId );
SET_THREADID(&f);
f.dirfd = -1;
@@ -696,9 +716,9 @@ static int unixOpenReadOnly(const char *zFilename, OsFile **pId){
if( f.h<0 ){
return SQLITE_CANTOPEN;
}
sqlite3Os.xEnterMutex();
sqlite3OsEnterMutex();
rc = findLockInfo(f.h, &f.pLock, &f.pOpen);
sqlite3Os.xLeaveMutex();
sqlite3OsLeaveMutex();
if( rc ){
close(f.h);
return SQLITE_NOMEM;
@@ -756,7 +776,7 @@ char *sqlite3_temp_directory = 0;
** Create a temporary file name in zBuf. zBuf must be big enough to
** hold at least SQLITE_TEMPNAME_SIZE characters.
*/
static int unixTempFileName(char *zBuf){
int sqlite3UnixTempFileName(char *zBuf){
static const char *azDirs[] = {
0,
"/var/tmp",
@@ -796,7 +816,7 @@ static int unixTempFileName(char *zBuf){
** Check that a given pathname is a directory and is writable
**
*/
static int unixIsDirWritable(char *zBuf){
int sqlite3UnixIsDirWritable(char *zBuf){
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
struct stat buf;
if( zBuf==0 ) return 0;
@@ -982,7 +1002,7 @@ static int unixSync(OsFile *id, int dataOnly){
** before making changes to individual journals on a multi-database commit.
** The F_FULLFSYNC option is not needed here.
*/
static int unixSyncDirectory(const char *zDirname){
int sqlite3UnixSyncDirectory(const char *zDirname){
#ifdef SQLITE_DISABLE_DIRSYNC
return SQLITE_OK;
#else
@@ -1035,7 +1055,7 @@ static int unixCheckReservedLock(OsFile *id){
assert( pFile );
if( CHECK_THREADID(pFile) ) return SQLITE_MISUSE;
sqlite3Os.xEnterMutex(); /* Because pFile->pLock is shared across threads */
sqlite3OsEnterMutex(); /* Because pFile->pLock is shared across threads */
/* Check if a thread in this process holds such a lock */
if( pFile->pLock->locktype>SHARED_LOCK ){
@@ -1056,7 +1076,7 @@ static int unixCheckReservedLock(OsFile *id){
}
}
sqlite3Os.xLeaveMutex();
sqlite3OsLeaveMutex();
TRACE3("TEST WR-LOCK %d %d\n", pFile->h, r);
return r;
@@ -1157,7 +1177,7 @@ static int unixLock(OsFile *id, int locktype){
/* If there is already a lock of this type or more restrictive on the
** OsFile, do nothing. Don't use the end_lock: exit path, as
** sqlite3Os.xEnterMutex() hasn't been called yet.
** sqlite3OsEnterMutex() hasn't been called yet.
*/
if( pFile->locktype>=locktype ){
TRACE3("LOCK %d %s ok (already held)\n", pFile->h,
@@ -1173,7 +1193,7 @@ static int unixLock(OsFile *id, int locktype){
/* This mutex is needed because pFile->pLock is shared across threads
*/
sqlite3Os.xEnterMutex();
sqlite3OsEnterMutex();
/* If some thread using this PID has a lock via a different OsFile*
** handle that precludes the requested lock, return BUSY.
@@ -1285,7 +1305,7 @@ static int unixLock(OsFile *id, int locktype){
}
end_lock:
sqlite3Os.xLeaveMutex();
sqlite3OsLeaveMutex();
TRACE4("LOCK %d %s %s\n", pFile->h, locktypeName(locktype),
rc==SQLITE_OK ? "ok" : "failed");
return rc;
@@ -1317,7 +1337,7 @@ static int unixUnlock(OsFile *id, int locktype){
if( pFile->locktype<=locktype ){
return SQLITE_OK;
}
sqlite3Os.xEnterMutex();
sqlite3OsEnterMutex();
pLock = pFile->pLock;
assert( pLock->cnt!=0 );
if( pFile->locktype>SHARED_LOCK ){
@@ -1378,7 +1398,7 @@ static int unixUnlock(OsFile *id, int locktype){
pOpen->aPending = 0;
}
}
sqlite3Os.xLeaveMutex();
sqlite3OsLeaveMutex();
pFile->locktype = locktype;
return rc;
}
@@ -1394,7 +1414,7 @@ static int unixClose(OsFile **pId){
unixUnlock(*pId, NO_LOCK);
if( id->dirfd>=0 ) close(id->dirfd);
id->dirfd = -1;
sqlite3Os.xEnterMutex();
sqlite3OsEnterMutex();
/* Disable the sqlite3_release_memory() function */
assert( !pTsd->disableReleaseMemory );
@@ -1426,7 +1446,7 @@ static int unixClose(OsFile **pId){
/* Disable the sqlite3_release_memory() function */
pTsd->disableReleaseMemory = 0;
sqlite3Os.xLeaveMutex();
sqlite3OsLeaveMutex();
id->isOpen = 0;
TRACE2("CLOSE %-3d\n", id->h);
OpenCounter(-1);
@@ -1441,7 +1461,7 @@ static int unixClose(OsFile **pId){
** The calling function is responsible for freeing this space once it
** is no longer needed.
*/
static char *unixFullPathname(const char *zRelative){
char *sqlite3UnixFullPathname(const char *zRelative){
char *zFull = 0;
if( zRelative[0]=='/' ){
sqlite3SetString(&zFull, zRelative, (char*)0);
@@ -1537,7 +1557,7 @@ static int allocateUnixFile(unixFile *pInit, OsFile **pId){
** is written into the buffer zBuf[256]. The calling function must
** supply a sufficiently large buffer.
*/
static int unixRandomSeed(char *zBuf){
int sqlite3UnixRandomSeed(char *zBuf){
/* We have to initialize zBuf to prevent valgrind from reporting
** errors. The reports issued by valgrind are incorrect - we would
** prefer that the randomness be increased by making use of the
@@ -1571,7 +1591,7 @@ static int unixRandomSeed(char *zBuf){
/*
** Sleep for a little while. Return the amount of time slept.
*/
static int unixSleep(int ms){
int sqlite3UnixSleep(int ms){
#if defined(HAVE_USLEEP) && HAVE_USLEEP
usleep(ms*1000);
return ms;
@@ -1597,14 +1617,14 @@ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
** SQLite uses only a single Mutex. There is not much critical
** code and what little there is executes quickly and without blocking.
*/
static void unixEnterMutex(){
void sqlite3UnixEnterMutex(){
#ifdef SQLITE_UNIX_THREADS
pthread_mutex_lock(&mutex);
#endif
assert( !inMutex );
inMutex = 1;
}
static void unixLeaveMutex(){
void sqlite3UnixLeaveMutex(){
assert( inMutex );
inMutex = 0;
#ifdef SQLITE_UNIX_THREADS
@@ -1618,7 +1638,7 @@ static void unixLeaveMutex(){
** for use in an assert() to verify that the mutex is held or not held
** in certain routines.
*/
static int unixInMutex(){
int sqlite3UnixInMutex(){
return inMutex;
}
@@ -1632,7 +1652,7 @@ static int unixInMutex(){
*/
#ifdef SQLITE_UNIX_THREADS
static void deleteTsd(void *pTsd){
sqlite3Os.xFree(pTsd);
sqlite3OsFree(pTsd);
}
#endif
@@ -1644,14 +1664,14 @@ static void deleteTsd(void *pTsd){
** 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){
void *sqlite3UnixThreadSpecificData(int nByte){
#ifdef SQLITE_UNIX_THREADS
static pthread_key_t key;
static int keyInit = 0;
void *pTsd;
if( !keyInit ){
sqlite3Os.xEnterMutex();
sqlite3OsEnterMutex();
if( !keyInit ){
int rc;
rc = pthread_key_create(&key, deleteTsd);
@@ -1660,12 +1680,12 @@ static void *unixThreadSpecificData(int nByte){
}
keyInit = 1;
}
sqlite3Os.xLeaveMutex();
sqlite3OsLeaveMutex();
}
pTsd = pthread_getspecific(key);
if( !pTsd ){
pTsd = sqlite3Os.xMalloc(nByte);
pTsd = sqlite3OsMalloc(nByte);
if( pTsd ){
memset(pTsd, 0, nByte);
pthread_setspecific(key, pTsd);
@@ -1675,7 +1695,7 @@ static void *unixThreadSpecificData(int nByte){
#else
static void *pTsd = 0;
if( !pTsd ){
pTsd = sqlite3Os.xMalloc(nByte);
pTsd = sqlite3OsMalloc(nByte);
if( pTsd ){
memset(pTsd, 0, nByte);
}
@@ -1686,7 +1706,7 @@ static void *unixThreadSpecificData(int nByte){
/*
** The following variable, if set to a non-zero value, becomes the result
** returned from sqlite3Os.xCurrentTime(). This is used for testing.
** returned from sqlite3OsCurrentTime(). This is used for testing.
*/
#ifdef SQLITE_TEST
int sqlite3_current_time = 0;
@@ -1697,7 +1717,7 @@ int sqlite3_current_time = 0;
** current time and date as a Julian Day number into *prNow and
** return 0. Return 1 if the time and date cannot be found.
*/
static int unixCurrentTime(double *prNow){
int sqlite3UnixCurrentTime(double *prNow){
#ifdef NO_GETTOD
time_t t;
time(&t);
@@ -1716,40 +1736,4 @@ static int unixCurrentTime(double *prNow){
return 0;
}
/* Macro used to comment out routines that do not exists when there is
** no disk I/O */
#ifdef SQLITE_OMIT_DISKIO
# define IF_DISKIO(X) 0
#else
# define IF_DISKIO(X) X
#endif
/*
** This is the structure that defines all of the I/O routines.
*/
struct sqlite3OsVtbl sqlite3Os = {
IF_DISKIO( unixOpenReadWrite ),
IF_DISKIO( unixOpenExclusive ),
IF_DISKIO( unixOpenReadOnly ),
IF_DISKIO( unixDelete ),
IF_DISKIO( unixFileExists ),
IF_DISKIO( unixFullPathname ),
IF_DISKIO( unixIsDirWritable ),
IF_DISKIO( unixSyncDirectory ),
IF_DISKIO( unixTempFileName ),
unixRandomSeed,
unixSleep,
unixCurrentTime,
unixEnterMutex,
unixLeaveMutex,
unixInMutex,
unixThreadSpecificData,
genericMalloc,
genericRealloc,
genericFree,
genericAllocationSize
};
#endif /* OS_UNIX */