diff options
author | drh <drh@noemail.net> | 2006-01-06 14:32:19 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2006-01-06 14:32:19 +0000 |
commit | 66560adab3473feb58436cb964f907ccd20991df (patch) | |
tree | cbf136dd406d0843cd2275e683e1e9a0af4a6928 /src/os_unix.c | |
parent | c87d34d05d7e6d9421e2b2eddcf51991067286b2 (diff) | |
download | sqlite-66560adab3473feb58436cb964f907ccd20991df.tar.gz sqlite-66560adab3473feb58436cb964f907ccd20991df.zip |
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
Diffstat (limited to 'src/os_unix.c')
-rw-r--r-- | src/os_unix.c | 130 |
1 files changed, 57 insertions, 73 deletions
diff --git a/src/os_unix.c b/src/os_unix.c index 2f90e3d47..1d74a884f 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -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 */ |