Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Further corrections to read-only SHM file handling on Win32. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | readonly-wal-recovery |
Files: | files | file ages | folders |
SHA3-256: |
43c311701bdf1202918cd46fa6133a11 |
User & Date: | mistachkin 2017-11-09 18:53:51.070 |
Context
2017-11-09
| ||
20:02 | Get read-only SHM file tests passing on Win32. (check-in: abef053535 user: mistachkin tags: readonly-wal-recovery) | |
18:53 | Further corrections to read-only SHM file handling on Win32. (check-in: 43c311701b user: mistachkin tags: readonly-wal-recovery) | |
18:21 | Corrections to Win32 lock detection for SHM files. (check-in: 3a91be975d user: mistachkin tags: readonly-wal-recovery) | |
Changes
Changes to src/os_win.c.
︙ | ︙ | |||
2101 2102 2103 2104 2105 2106 2107 | /* ** The "winIsLockingError" macro is used to determine if a particular I/O ** error code is due to file locking. It must accept the error code DWORD ** as its only argument and should return non-zero if the error code is due ** to file locking. */ #if !defined(winIsLockingError) | | > | 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 | /* ** The "winIsLockingError" macro is used to determine if a particular I/O ** error code is due to file locking. It must accept the error code DWORD ** as its only argument and should return non-zero if the error code is due ** to file locking. */ #if !defined(winIsLockingError) #define winIsLockingError(a) (((a)==NO_ERROR) || \ ((a)==ERROR_LOCK_VIOLATION) || \ ((a)==ERROR_HANDLE_EOF) || \ ((a)==ERROR_IO_PENDING)) #endif /* ** The "winIoerrCanRetry1" macro is used to determine if a particular I/O ** error code obtained via GetLastError() is eligible to be retried. It ** must accept the error code DWORD as its only argument and should return |
︙ | ︙ | |||
3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 | ** ** WINSHM_UNLCK -- No locks are held on the DMS. ** WINSHM_RDLCK -- A SHARED lock is held on the DMS. ** WINSHM_WRLCK -- An EXCLUSIVE lock is held on the DMS. */ static int winGetShmDmsLockType( winFile *pFile, /* File handle object */ int *pLockType /* WINSHM_UNLCK, WINSHM_RDLCK, or WINSHM_WRLCK */ ){ #if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) OVERLAPPED overlapped; /* The offset for ReadFile/WriteFile. */ #endif LPVOID pOverlapped = 0; sqlite3_int64 offset = WIN_SHM_DMS; BYTE notUsed1 = 0; DWORD notUsed2 = 0; #if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED) if( winSeekFile(pFile, offset) ){ return SQLITE_IOERR_SEEK; } #else memset(&overlapped, 0, sizeof(OVERLAPPED)); overlapped.Offset = (LONG)(offset & 0xffffffff); overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); pOverlapped = &overlapped; #endif | > > | | | | | | 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 | ** ** WINSHM_UNLCK -- No locks are held on the DMS. ** WINSHM_RDLCK -- A SHARED lock is held on the DMS. ** WINSHM_WRLCK -- An EXCLUSIVE lock is held on the DMS. */ static int winGetShmDmsLockType( winFile *pFile, /* File handle object */ int bReadOnly, /* Non-zero if the SHM was opened read-only */ int *pLockType /* WINSHM_UNLCK, WINSHM_RDLCK, or WINSHM_WRLCK */ ){ #if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) OVERLAPPED overlapped; /* The offset for ReadFile/WriteFile. */ #endif LPVOID pOverlapped = 0; sqlite3_int64 offset = WIN_SHM_DMS; BYTE notUsed1 = 0; DWORD notUsed2 = 0; #if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED) if( winSeekFile(pFile, offset) ){ return SQLITE_IOERR_SEEK; } #else memset(&overlapped, 0, sizeof(OVERLAPPED)); overlapped.Offset = (LONG)(offset & 0xffffffff); overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); pOverlapped = &overlapped; #endif if( bReadOnly || !osWriteFile(pFile->h, ¬Used1, 1, ¬Used2, pOverlapped) ){ DWORD lastErrno = bReadOnly ? NO_ERROR : osGetLastError(); if( !osReadFile(pFile->h, ¬Used1, 1, ¬Used2, pOverlapped) ){ lastErrno = osGetLastError(); if( winIsLockingError(lastErrno) ){ if( pLockType ) *pLockType = WINSHM_WRLCK; }else{ return SQLITE_IOERR_READ; } }else{ if( winIsLockingError(lastErrno) ){ if( pLockType ) *pLockType = WINSHM_RDLCK; }else{ return SQLITE_IOERR_WRITE; } } }else{ if( pLockType ) *pLockType = WINSHM_UNLCK; } return SQLITE_OK; } /* ** The DMS lock has not yet been taken on shm file pShmNode. Attempt to ** take it now. Return SQLITE_OK if successful, or an SQLite error |
︙ | ︙ | |||
3916 3917 3918 3919 3920 3921 3922 | ** return SQLITE_BUSY to the caller (it will try again). An earlier ** version of this code attempted the SHARED lock at this point. But ** this introduced a subtle race condition: if the process holding ** EXCLUSIVE failed just before truncating the *-shm file, then this ** process might open and use the *-shm file without truncating it. ** And if the *-shm file has been corrupted by a power failure or ** system crash, the database itself may also become corrupt. */ | | > | 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 | ** return SQLITE_BUSY to the caller (it will try again). An earlier ** version of this code attempted the SHARED lock at this point. But ** this introduced a subtle race condition: if the process holding ** EXCLUSIVE failed just before truncating the *-shm file, then this ** process might open and use the *-shm file without truncating it. ** And if the *-shm file has been corrupted by a power failure or ** system crash, the database itself may also become corrupt. */ if( winGetShmDmsLockType(&pShmNode->hFile, pShmNode->isReadonly, &lockType)!=SQLITE_OK ){ rc = SQLITE_IOERR_LOCK; }else if( lockType==WINSHM_UNLCK ){ if( pShmNode->isReadonly ){ pShmNode->isUnlocked = 1; rc = SQLITE_READONLY_CANTINIT; }else{ winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); |
︙ | ︙ |