?? os.c
字號:
if( isNT() ){ UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0); }else{ res = UnlockFile(id->h, FIRST_LOCKBYTE + id->locked, 0, 1, 0); } } if( res ){ res = LockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0); }else{ res = 0; } UnlockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0); } if( res ){ id->locked = -1; rc = SQLITE_OK; }else{ rc = SQLITE_BUSY; } } return rc;# else int decCount = 0; // if already write locked, return success if ( id->locked < 0 ) return SQLITE_OK; // If file not shared, always success if ( id->hMux == 0 ) { id->locked = -1; return SQLITE_OK; }# ifndef SQLITE_WCE_OMIT_FILELOCK // Lock file for all processes if ( ! wceport_LockFileMutex(id->hMux) ) return SQLITE_BUSY; // If I have a read-lock, release lock if ( id->locked > 0 && sqliteOsUnlock(id) != SQLITE_OK ) { ReleaseSemaphore( id->hSem, 1, NULL ); id->locked = 0; } // try to decrement semaphore to non-signaled state decCount = id->locked > 0 ? MAX_FILE_READERS - 1 : MAX_FILE_READERS; if ( ! wceport_DecrementSemaphoreN(id->hSem,decCount) ) { // Someone is locking the file (reader or writer) ReleaseMutex( id->hMux ); return SQLITE_BUSY; } // success id->locked = -1; ReleaseMutex( id->hMux );# else // SQLITE_OMIT_FILELOCK id->locked = -1;# endif return SQLITE_OK;# endif#endif#if OS_MAC int rc; if( id->locked<0 || id->refNumRF == -1 ){ rc = SQLITE_OK; }else{ OSErr res; int cnt = 5; ParamBlockRec params; memset(¶ms, 0, sizeof(params)); params.ioParam.ioRefNum = id->refNumRF; params.ioParam.ioPosMode = fsFromStart; params.ioParam.ioPosOffset = FIRST_LOCKBYTE; params.ioParam.ioReqCount = 1; while( cnt-->0 && (res = PBLockRangeSync(¶ms))!=noErr ){ UInt32 finalTicks; Delay(1, &finalTicks); /* 1/60 sec */ } if( res == noErr ){ params.ioParam.ioPosOffset = FIRST_LOCKBYTE + id->locked; params.ioParam.ioReqCount = 1; if( id->locked==0 || PBUnlockRangeSync(¶ms)==noErr ){ params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1; params.ioParam.ioReqCount = N_LOCKBYTE; res = PBLockRangeSync(¶ms); }else{ res = afpRangeNotLocked; } params.ioParam.ioPosOffset = FIRST_LOCKBYTE; params.ioParam.ioReqCount = 1; PBUnlockRangeSync(¶ms); } if( res == noErr ){ id->locked = -1; rc = SQLITE_OK; }else{ rc = SQLITE_BUSY; } } return rc;#endif}/*** Unlock the given file descriptor. If the file descriptor was** not previously locked, then this routine is a no-op. If this** library was compiled with large file support (LFS) but LFS is not** available on the host, then an SQLITE_NOLFS is returned.*/int sqliteOsUnlock(OsFile *id){#if OS_UNIX int rc; if( !id->locked ) return SQLITE_OK; sqliteOsEnterMutex(); assert( id->pLock->cnt!=0 ); if( id->pLock->cnt>1 ){ id->pLock->cnt--; rc = SQLITE_OK; }else{ struct flock lock; int s; lock.l_type = F_UNLCK; lock.l_whence = SEEK_SET; lock.l_start = lock.l_len = 0L; s = fcntl(id->fd, F_SETLK, &lock); if( s!=0 ){ rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY; }else{ rc = SQLITE_OK; id->pLock->cnt = 0; } } if( rc==SQLITE_OK ){ /* Decrement the count of locks against this same file. When the ** count reaches zero, close any other file descriptors whose close ** was deferred because of outstanding locks. */ struct openCnt *pOpen = id->pOpen; pOpen->nLock--; assert( pOpen->nLock>=0 ); if( pOpen->nLock==0 && pOpen->nPending>0 ){ int i; for(i=0; i<pOpen->nPending; i++){ close(pOpen->aPending[i]); } sqliteFree(pOpen->aPending); pOpen->nPending = 0; pOpen->aPending = 0; } } sqliteOsLeaveMutex(); id->locked = 0; return rc;#endif#if OS_WIN# ifndef _WIN32_WCE int rc; if( id->locked==0 ){ rc = SQLITE_OK; }else if( isNT() || id->locked<0 ){ UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0); rc = SQLITE_OK; id->locked = 0; }else{ UnlockFile(id->h, FIRST_LOCKBYTE+id->locked, 0, 1, 0); rc = SQLITE_OK; id->locked = 0; } return rc;# else if ( id->locked == 0 || id->hMux == 0 ) { id->locked = 0; return SQLITE_OK; }# ifndef SQLITE_WCE_OMIT_FILELOCK // Lock file for all processes if ( ! wceport_LockFileMutex(id->hMux) ) return SQLITE_BUSY; // This cannot happen if ( id->locked < 0 ) { // Write locked wceport_IncrementSemaphoreN( id->hSem, MAX_FILE_READERS ); } else { // Read locked wceport_IncrementSemaphoreN( id->hSem, 1 ); } // Update lock status and release file mutex lock id->locked = 0; ReleaseMutex( id->hMux );# else // SQLITE_OMIT_FILELOCK id->locked = 0;# endif // SQLITE_OMIT_FILELOCK return SQLITE_OK;# endif#endif#if OS_MAC int rc; ParamBlockRec params; memset(¶ms, 0, sizeof(params)); params.ioParam.ioRefNum = id->refNumRF; params.ioParam.ioPosMode = fsFromStart; if( id->locked==0 || id->refNumRF == -1 ){ rc = SQLITE_OK; }else if( id->locked<0 ){ params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1; params.ioParam.ioReqCount = N_LOCKBYTE; PBUnlockRangeSync(¶ms); rc = SQLITE_OK; id->locked = 0; }else{ params.ioParam.ioPosOffset = FIRST_LOCKBYTE+id->locked; params.ioParam.ioReqCount = 1; PBUnlockRangeSync(¶ms); rc = SQLITE_OK; id->locked = 0; } return rc;#endif}/*** Get information to seed the random number generator. The seed** is written into the buffer zBuf[256]. The calling function must** supply a sufficiently large buffer.*/int sqliteOsRandomSeed(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 ** uninitialized space in zBuf - but valgrind errors tend to worry ** some users. Rather than argue, it seems easier just to initialize ** the whole array and silence valgrind, even if that means less randomness ** in the random seed. ** ** When testing, initializing zBuf[] to zero is all we do. That means ** that we always use the same random number sequence.* This makes the ** tests repeatable. */ memset(zBuf, 0, 256);#if OS_UNIX && !defined(SQLITE_TEST) { int pid; time((time_t*)zBuf); pid = getpid(); memcpy(&zBuf[sizeof(time_t)], &pid, sizeof(pid)); }#endif#if OS_WIN && !defined(SQLITE_TEST) GetSystemTime((LPSYSTEMTIME)zBuf);#endif#if OS_MAC { int pid; Microseconds((UnsignedWide*)zBuf); pid = getpid(); memcpy(&zBuf[sizeof(UnsignedWide)], &pid, sizeof(pid)); }#endif return SQLITE_OK;}/*** Sleep for a little while. Return the amount of time slept.*/int sqliteOsSleep(int ms){#if OS_UNIX#if defined(HAVE_USLEEP) && HAVE_USLEEP usleep(ms*1000); return ms;#else sleep((ms+999)/1000); return 1000*((ms+999)/1000);#endif#endif#if OS_WIN Sleep(ms); return ms;#endif#if OS_MAC UInt32 finalTicks; UInt32 ticks = (((UInt32)ms+16)*3)/50; /* 1/60 sec per tick */ Delay(ticks, &finalTicks); return (int)((ticks*50)/3);#endif}/*** Static variables used for thread synchronization*/static int inMutex = 0;#ifdef SQLITE_UNIX_THREADS static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;#endif#ifdef SQLITE_W32_THREADS static CRITICAL_SECTION cs;#endif#ifdef SQLITE_MACOS_MULTITASKING static MPCriticalRegionID criticalRegion;#endif/*** The following pair of routine implement mutual exclusion for** multi-threaded processes. Only a single thread is allowed to** executed code that is surrounded by EnterMutex() and LeaveMutex().**** SQLite uses only a single Mutex. There is not much critical** code and what little there is executes quickly and without blocking.*/void sqliteOsEnterMutex(){#ifdef SQLITE_UNIX_THREADS pthread_mutex_lock(&mutex);#endif#ifdef SQLITE_W32_THREADS static int isInit = 0; while( !isInit ){ static long lock = 0; if( InterlockedIncrement(&lock)==1 ){ InitializeCriticalSection(&cs); isInit = 1; }else{ Sleep(1); } } EnterCriticalSection(&cs);#endif#ifdef SQLITE_MACOS_MULTITASKING static volatile int notInit = 1; if( notInit ){ if( notInit == 2 ) /* as close as you can get to thread safe init */ MPYield(); else{ notInit = 2; MPCreateCriticalRegion(&criticalRegion); notInit = 0; } } MPEnterCriticalRegion(criticalRegion, kDurationForever);#endif assert( !inMutex ); inMutex = 1;}void sqliteOsLeaveMutex(){ assert( inMutex ); inMutex = 0;#ifdef SQLITE_UNIX_THREADS pthread_mutex_unlock(&mutex);#endif#ifdef SQLITE_W32_THREADS LeaveCriticalSection(&cs);#endif#ifdef SQLITE_MACOS_MULTITASKING MPExitCriticalRegion(criticalRegion);#endif}/*** Turn a relative pathname into a full pathname. Return a pointer** to the full pathname stored in space obtained from sqliteMalloc().** The calling function is responsible for freeing this space once it** is no longer needed.*/char *sqliteOsFullPathname(const char *zRelative){#if OS_UNIX char *zFull = 0; if( zRelative[0]=='/' ){ sqliteSetString(&zFull, zRelative, (char*)0); }else{ char zBuf[5000]; sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), "/", zRelative, (char*)0); } return zFull;#endif#if OS_WIN# ifndef _WIN32_WCE char *zNotUsed; char *zFull; int nByte; nByte = GetFullPathName(zRelative, 0, 0, &zNotUsed) + 1; zFull = sqliteMalloc( nByte ); if( zFull==0 ) return 0; GetFullPathName(zRelative, nByte, zFull, &zNotUsed);# else // There is no current directory on Windows CE, so we assume // we are working always with absolute paths char *zFull = 0; sqliteSetString( &zFull, zRelative, 0 );# endif return zFull;#endif#if OS_MAC char *zFull = 0; if( zRelative[0]==':' ){ char zBuf[_MAX_PATH+1]; sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), &(zRelative[1]), (char*)0); }else{ if( strchr(zRelative, ':') ){ sqliteSetString(&zFull, zRelative, (char*)0); }else{ char zBuf[_MAX_PATH+1]; sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), zRelative, (char*)0); } } return zFull;#endif}/*** The following variable, if set to a non-zero value, becomes the result** returned from sqliteOsCurrentTime(). This is used for testing.*/#ifdef SQLITE_TESTint sqlite_current_time = 0;#endif/*** Find the current time (in Universal Coordinated Time). Write the** current time and date as a Julian Day number into *prNow and** return 0. Return 1 if the time and date cannot be found.*/int sqliteOsCurrentTime(double *prNow){#if OS_UNIX time_t t; time(&t); *prNow = t/86400.0 + 2440587.5;#endif#if OS_WIN FILETIME ft; /* FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). */ double now;#ifndef _WIN32_WCE GetSystemTimeAsFileTime( &ft );#else { /* WinCE doesn't have GetSystemTimeAsFileTime() */ SYSTEMTIME st; GetSystemTime( &st ); SystemTimeToFileTime( &st, &ft ); }#endif now = ((double)ft.dwHighDateTime) * 4294967296.0; *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;#endif#ifdef SQLITE_TEST if( sqlite_current_time ){ *prNow = sqlite_current_time/86400.0 + 2440587.5; }#endif return 0;}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -