Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Simplifications to the SHM locking implementation in os_unix.c. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
9de05bfb09e29bafdf5782263330fe8e |
User & Date: | drh 2010-05-05 18:20:07.000 |
Context
2010-05-05
| ||
18:46 | Do not compare page sizes on source and destination of backup until transactions are started and the page sizes are locked. This is a fix to check-in [7bd44794c4]. (check-in: ec7157788b user: drh tags: trunk) | |
18:20 | Simplifications to the SHM locking implementation in os_unix.c. (check-in: 9de05bfb09 user: drh tags: trunk) | |
16:23 | Prohibit backup if the destination is using WAL and has a different page size from the source. (check-in: 7bd44794c4 user: drh tags: trunk) | |
Changes
Changes to src/os_unix.c.
︙ | ︙ | |||
4644 4645 4646 4647 4648 4649 4650 | ** The unixShm.pFile element is initialized when the object is created ** and is read-only thereafter. */ struct unixShm { unixShmFile *pFile; /* The underlying unixShmFile object */ unixShm *pNext; /* Next unixShm with the same unixShmFile */ u8 lockState; /* Current lock state */ | < < | | 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 | ** The unixShm.pFile element is initialized when the object is created ** and is read-only thereafter. */ struct unixShm { unixShmFile *pFile; /* The underlying unixShmFile object */ unixShm *pNext; /* Next unixShm with the same unixShmFile */ u8 lockState; /* Current lock state */ u8 hasMutex; /* True if holding the unixShmFile mutex */ u8 hasMutexBuf; /* True if holding pFile->mutexBuf */ u8 sharedMask; /* Mask of shared locks held */ u8 exclMask; /* Mask of exclusive locks held */ #ifdef SQLITE_DEBUG u8 id; /* Id of this connection with its unixShmFile */ #endif }; /* ** Size increment by which shared memory grows */ #define SQLITE_UNIX_SHM_INCR 4096 /* ** Constants used for locking */ #define UNIX_SHM_BASE 32 /* Byte offset of the first lock byte */ #define UNIX_SHM_DMS 0x01 /* Mask for Dead-Man-Switch lock */ #define UNIX_SHM_A 0x10 /* Mask for region locks... */ #define UNIX_SHM_B 0x20 #define UNIX_SHM_C 0x40 #define UNIX_SHM_D 0x80 #ifdef SQLITE_DEBUG /* |
︙ | ︙ | |||
4691 4692 4693 4694 4695 4696 4697 | static int iBuf = 0; char *z; z = &zBuf[iBuf]; iBuf += 8; if( iBuf>=sizeof(zBuf) ) iBuf = 0; | < | | | | | | | | | 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 | static int iBuf = 0; char *z; z = &zBuf[iBuf]; iBuf += 8; if( iBuf>=sizeof(zBuf) ) iBuf = 0; z[0] = (mask & UNIX_SHM_DMS) ? 'S' : '.'; z[1] = (mask & UNIX_SHM_A) ? 'A' : '.'; z[2] = (mask & UNIX_SHM_B) ? 'B' : '.'; z[3] = (mask & UNIX_SHM_C) ? 'C' : '.'; z[4] = (mask & UNIX_SHM_D) ? 'D' : '.'; z[5] = 0; return z; } #endif /* SQLITE_DEBUG */ /* ** Apply posix advisory locks for all bytes identified in lockMask. ** ** lockMask might contain multiple bits but all bits are guaranteed ** to be contiguous. ** ** Locks block if the mask is exactly UNIX_SHM_C and are non-blocking ** otherwise. */ static int unixShmSystemLock( unixShmFile *pFile, /* Apply locks to this open shared-memory segment */ int lockType, /* F_UNLCK, F_RDLCK, or F_WRLCK */ u8 lockMask /* Which bytes to lock or unlock */ ){ struct flock f; /* The posix advisory locking structure */ int lockOp; /* The opcode for fcntl() */ int i; /* Offset into the locking byte range */ int rc; /* Result code form fcntl() */ u8 mask; /* Mask of bits in lockMask */ /* Access to the unixShmFile object is serialized by the caller */ assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 ); /* Initialize the locking parameters */ memset(&f, 0, sizeof(f)); f.l_type = lockType; f.l_whence = SEEK_SET; if( lockMask==UNIX_SHM_C && lockType!=F_UNLCK ){ lockOp = F_SETLKW; OSTRACE(("SHM-LOCK requesting blocking lock\n")); }else{ lockOp = F_SETLK; } /* Find the first bit in lockMask that is set */ |
︙ | ︙ | |||
5025 5026 5027 5028 5029 5030 5031 | } pFile->fid.dev = sStat.st_dev; pFile->fid.ino = sStat.st_ino; /* Check to see if another process is holding the dead-man switch. ** If not, truncate the file to zero length. */ | < < < < < | 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 | } pFile->fid.dev = sStat.st_dev; pFile->fid.ino = sStat.st_ino; /* Check to see if another process is holding the dead-man switch. ** If not, truncate the file to zero length. */ if( unixShmSystemLock(pFile, F_WRLCK, UNIX_SHM_DMS)==SQLITE_OK ){ if( ftruncate(pFile->h, 0) ){ rc = SQLITE_IOERR; } } if( rc==SQLITE_OK ){ rc = unixShmSystemLock(pFile, F_RDLCK, UNIX_SHM_DMS); } if( rc ) goto shm_open_err; } /* Make the new connection a child of the unixShmFile */ p->pFile = pFile; p->pNext = pFile->pFirst; #ifdef SQLITE_DEBUG |
︙ | ︙ | |||
5317 5318 5319 5320 5321 5322 5323 | rc = SQLITE_BUSY; assert( p->lockState==SQLITE_SHM_UNLOCK ); for(nAttempt=0; nAttempt<5 && rc==SQLITE_BUSY; nAttempt++){ rc = unixShmSharedLock(pFile, p, UNIX_SHM_A|UNIX_SHM_B); if( rc==SQLITE_BUSY ){ rc = unixShmSharedLock(pFile, p, UNIX_SHM_D); if( rc==SQLITE_OK ){ | | | | | | | | 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 | rc = SQLITE_BUSY; assert( p->lockState==SQLITE_SHM_UNLOCK ); for(nAttempt=0; nAttempt<5 && rc==SQLITE_BUSY; nAttempt++){ rc = unixShmSharedLock(pFile, p, UNIX_SHM_A|UNIX_SHM_B); if( rc==SQLITE_BUSY ){ rc = unixShmSharedLock(pFile, p, UNIX_SHM_D); if( rc==SQLITE_OK ){ p->lockState = SQLITE_SHM_READ_FULL; } }else{ unixShmUnlock(pFile, p, UNIX_SHM_B); p->lockState = SQLITE_SHM_READ; } } }else if( p->lockState==SQLITE_SHM_WRITE ){ rc = unixShmSharedLock(pFile, p, UNIX_SHM_A); unixShmUnlock(pFile, p, UNIX_SHM_C|UNIX_SHM_D); p->lockState = SQLITE_SHM_READ; }else{ assert( p->lockState==SQLITE_SHM_RECOVER ); unixShmUnlock(pFile, p, UNIX_SHM_C); p->lockState = SQLITE_SHM_READ; rc = SQLITE_OK; } break; } case SQLITE_SHM_WRITE: { assert( p->lockState==SQLITE_SHM_READ || p->lockState==SQLITE_SHM_READ_FULL ); rc = unixShmExclusiveLock(pFile, p, UNIX_SHM_C|UNIX_SHM_D); if( rc==SQLITE_OK ){ p->lockState = SQLITE_SHM_WRITE; } break; } case SQLITE_SHM_CHECKPOINT: { assert( p->lockState==SQLITE_SHM_UNLOCK || p->lockState==SQLITE_SHM_PENDING || p->lockState==SQLITE_SHM_RECOVER ); if( p->lockState==SQLITE_SHM_RECOVER ){ unixShmUnlock(pFile, p, UNIX_SHM_C); p->lockState = SQLITE_SHM_CHECKPOINT; rc = SQLITE_OK; } if( p->lockState==SQLITE_SHM_UNLOCK ){ rc = unixShmExclusiveLock(pFile, p, UNIX_SHM_B|UNIX_SHM_C); if( rc==SQLITE_OK ){ p->lockState = SQLITE_SHM_PENDING; |
︙ | ︙ | |||
5374 5375 5376 5377 5378 5379 5380 | } default: { assert( desiredLock==SQLITE_SHM_RECOVER ); assert( p->lockState==SQLITE_SHM_READ || p->lockState==SQLITE_SHM_READ_FULL || p->lockState==SQLITE_SHM_CHECKPOINT ); assert( sqlite3_mutex_held(pFile->mutexBuf) ); | | | 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 | } default: { assert( desiredLock==SQLITE_SHM_RECOVER ); assert( p->lockState==SQLITE_SHM_READ || p->lockState==SQLITE_SHM_READ_FULL || p->lockState==SQLITE_SHM_CHECKPOINT ); assert( sqlite3_mutex_held(pFile->mutexBuf) ); rc = unixShmExclusiveLock(pFile, p, UNIX_SHM_C); if( rc==SQLITE_OK ){ p->lockState = SQLITE_SHM_RECOVER; } break; } } sqlite3_mutex_leave(pFile->mutex); |
︙ | ︙ |