📄 os_win.c
字号:
** Destroy the part of winFile that deals with wince locks*/static void winceDestroyLock(winFile *pFile){ if (pFile->hMutex){ /* Acquire the mutex */ winceMutexAcquire(pFile->hMutex); /* The following blocks should probably assert in debug mode, but they are to cleanup in case any locks remained open */ if (pFile->local.nReaders){ pFile->shared->nReaders --; } if (pFile->local.bReserved){ pFile->shared->bReserved = FALSE; } if (pFile->local.bPending){ pFile->shared->bPending = FALSE; } if (pFile->local.bExclusive){ pFile->shared->bExclusive = FALSE; } /* De-reference and close our copy of the shared memory handle */ UnmapViewOfFile(pFile->shared); CloseHandle(pFile->hShared); /* Done with the mutex */ winceMutexRelease(pFile->hMutex); CloseHandle(pFile->hMutex); pFile->hMutex = NULL; }}/* ** An implementation of the LockFile() API of windows for wince*/static BOOL winceLockFile( HANDLE *phFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh, DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh){ winFile *pFile = HANDLE_TO_WINFILE(phFile); BOOL bReturn = FALSE; if (!pFile->hMutex) return TRUE; winceMutexAcquire(pFile->hMutex); /* Wanting an exclusive lock? */ if (dwFileOffsetLow == SHARED_FIRST && nNumberOfBytesToLockLow == SHARED_SIZE){ if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){ pFile->shared->bExclusive = TRUE; pFile->local.bExclusive = TRUE; bReturn = TRUE; } } /* Want a read-only lock? */ else if ((dwFileOffsetLow >= SHARED_FIRST && dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE) && nNumberOfBytesToLockLow == 1){ if (pFile->shared->bExclusive == 0){ pFile->local.nReaders ++; if (pFile->local.nReaders == 1){ pFile->shared->nReaders ++; } bReturn = TRUE; } } /* Want a pending lock? */ else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToLockLow == 1){ /* If no pending lock has been acquired, then acquire it */ if (pFile->shared->bPending == 0) { pFile->shared->bPending = TRUE; pFile->local.bPending = TRUE; bReturn = TRUE; } } /* Want a reserved lock? */ else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToLockLow == 1){ if (pFile->shared->bReserved == 0) { pFile->shared->bReserved = TRUE; pFile->local.bReserved = TRUE; bReturn = TRUE; } } winceMutexRelease(pFile->hMutex); return bReturn;}/*** An implementation of the UnlockFile API of windows for wince*/static BOOL winceUnlockFile( HANDLE *phFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh, DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh){ winFile *pFile = HANDLE_TO_WINFILE(phFile); BOOL bReturn = FALSE; if (!pFile->hMutex) return TRUE; winceMutexAcquire(pFile->hMutex); /* Releasing a reader lock or an exclusive lock */ if (dwFileOffsetLow >= SHARED_FIRST && dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE){ /* Did we have an exclusive lock? */ if (pFile->local.bExclusive){ pFile->local.bExclusive = FALSE; pFile->shared->bExclusive = FALSE; bReturn = TRUE; } /* Did we just have a reader lock? */ else if (pFile->local.nReaders){ pFile->local.nReaders --; if (pFile->local.nReaders == 0) { pFile->shared->nReaders --; } bReturn = TRUE; } } /* Releasing a pending lock */ else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){ if (pFile->local.bPending){ pFile->local.bPending = FALSE; pFile->shared->bPending = FALSE; bReturn = TRUE; } } /* Releasing a reserved lock */ else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){ if (pFile->local.bReserved) { pFile->local.bReserved = FALSE; pFile->shared->bReserved = FALSE; bReturn = TRUE; } } winceMutexRelease(pFile->hMutex); return bReturn;}/*** An implementation of the LockFileEx() API of windows for wince*/static BOOL winceLockFileEx( HANDLE *phFile, DWORD dwFlags, DWORD dwReserved, DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh, LPOVERLAPPED lpOverlapped){ /* If the caller wants a shared read lock, forward this call ** to winceLockFile */ if (lpOverlapped->Offset == SHARED_FIRST && dwFlags == 1 && nNumberOfBytesToLockLow == SHARED_SIZE){ return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0); } return FALSE;}/*** End of the special code for wince*****************************************************************************/#endif /* SQLITE_OS_WINCE *//******************************************************************************* The next group of routines implement the I/O methods specified** by the sqlite3_io_methods object.******************************************************************************//*** Close a file.**** It is reported that an attempt to close a handle might sometimes** fail. This is a very unreasonable result, but windows is notorious** for being unreasonable so I do not doubt that it might happen. If** the close fails, we pause for 100 milliseconds and try again. As** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before** giving up and returning an error.*/#define MX_CLOSE_ATTEMPT 3static int winClose(sqlite3_file *id){ int rc, cnt = 0; winFile *pFile = (winFile*)id; OSTRACE2("CLOSE %d\n", pFile->h); do{ rc = CloseHandle(pFile->h); }while( rc==0 && cnt++ < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );#if SQLITE_OS_WINCE#define WINCE_DELETION_ATTEMPTS 3 winceDestroyLock(pFile); if( pFile->zDeleteOnClose ){ int cnt = 0; while( DeleteFileW(pFile->zDeleteOnClose)==0 && GetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff && cnt++ < WINCE_DELETION_ATTEMPTS ){ Sleep(100); /* Wait a little before trying again */ } free(pFile->zDeleteOnClose); }#endif OpenCounter(-1); return rc ? SQLITE_OK : SQLITE_IOERR;}/*** Some microsoft compilers lack this definition.*/#ifndef INVALID_SET_FILE_POINTER# define INVALID_SET_FILE_POINTER ((DWORD)-1)#endif/*** Read data from a file into a buffer. Return SQLITE_OK if all** bytes were read successfully and SQLITE_IOERR if anything goes** wrong.*/static int winRead( sqlite3_file *id, /* File to read from */ void *pBuf, /* Write content into this buffer */ int amt, /* Number of bytes to read */ sqlite3_int64 offset /* Begin reading at this offset */){ LONG upperBits = (offset>>32) & 0x7fffffff; LONG lowerBits = offset & 0xffffffff; DWORD rc; DWORD got; winFile *pFile = (winFile*)id; assert( id!=0 ); SimulateIOError(return SQLITE_IOERR_READ); OSTRACE3("READ %d lock=%d\n", pFile->h, pFile->locktype); rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){ return SQLITE_FULL; } if( !ReadFile(pFile->h, pBuf, amt, &got, 0) ){ return SQLITE_IOERR_READ; } if( got==(DWORD)amt ){ return SQLITE_OK; }else{ memset(&((char*)pBuf)[got], 0, amt-got); return SQLITE_IOERR_SHORT_READ; }}/*** Write data from a buffer into a file. Return SQLITE_OK on success** or some other error code on failure.*/static int winWrite( sqlite3_file *id, /* File to write into */ const void *pBuf, /* The bytes to be written */ int amt, /* Number of bytes to write */ sqlite3_int64 offset /* Offset into the file to begin writing at */){ LONG upperBits = (offset>>32) & 0x7fffffff; LONG lowerBits = offset & 0xffffffff; DWORD rc; DWORD wrote; winFile *pFile = (winFile*)id; assert( id!=0 ); SimulateIOError(return SQLITE_IOERR_WRITE); SimulateDiskfullError(return SQLITE_FULL); OSTRACE3("WRITE %d lock=%d\n", pFile->h, pFile->locktype); rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){ return SQLITE_FULL; } assert( amt>0 ); while( amt>0 && (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0 && wrote>0 ){ amt -= wrote; pBuf = &((char*)pBuf)[wrote]; } if( !rc || amt>(int)wrote ){ return SQLITE_FULL; } return SQLITE_OK;}/*** Truncate an open file to a specified size*/static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ LONG upperBits = (nByte>>32) & 0x7fffffff; LONG lowerBits = nByte & 0xffffffff; winFile *pFile = (winFile*)id; OSTRACE3("TRUNCATE %d %lld\n", pFile->h, nByte); SimulateIOError(return SQLITE_IOERR_TRUNCATE); SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); SetEndOfFile(pFile->h); return SQLITE_OK;}#ifdef SQLITE_TEST/*** Count the number of fullsyncs and normal syncs. This is used to test** that syncs and fullsyncs are occuring at the right times.*/int sqlite3_sync_count = 0;int sqlite3_fullsync_count = 0;#endif/*** Make sure all writes to a particular file are committed to disk.*/static int winSync(sqlite3_file *id, int flags){ winFile *pFile = (winFile*)id; OSTRACE3("SYNC %d lock=%d\n", pFile->h, pFile->locktype);#ifdef SQLITE_TEST if( flags & SQLITE_SYNC_FULL ){ sqlite3_fullsync_count++; } sqlite3_sync_count++;#endif if( FlushFileBuffers(pFile->h) ){ return SQLITE_OK; }else{ return SQLITE_IOERR; }}/*** Determine the current size of a file in bytes*/static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ winFile *pFile = (winFile*)id; DWORD upperBits, lowerBits; SimulateIOError(return SQLITE_IOERR_FSTAT); lowerBits = GetFileSize(pFile->h, &upperBits); *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; return SQLITE_OK;}/*** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.*/#ifndef LOCKFILE_FAIL_IMMEDIATELY# define LOCKFILE_FAIL_IMMEDIATELY 1#endif/*** Acquire a reader lock.** Different API routines are called depending on whether or not this** is Win95 or WinNT.*/static int getReadLock(winFile *pFile){ int res; if( isNT() ){ OVERLAPPED ovlp; ovlp.Offset = SHARED_FIRST; ovlp.OffsetHigh = 0; ovlp.hEvent = 0; res = LockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY, 0, SHARED_SIZE, 0, &ovlp); }else{ int lk; sqlite3_randomness(sizeof(lk), &lk); pFile->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1); res = LockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); } return res;}/*** Undo a readlock*/static int unlockReadLock(winFile *pFile){ int res; if( isNT() ){ res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); }else{ res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0); } return res;}/*** Lock the file with the lock specified by parameter locktype - one** of the following:**** (1) SHARED_LOCK** (2) RESERVED_LOCK** (3) PENDING_LOCK** (4) EXCLUSIVE_LOCK**** Sometimes when requesting one lock state, additional lock states** are inserted in between. The locking might fail on one of the later
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -