Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fixes to the OsUnlock() interface. Correctly leave a SHARED lock behind when requested. Honor the error code that OsUnlock() returns. Ticket #913 and #938. (CVS 1997) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
c4697503d0ad080290b91e96dfc9a1a6 |
User & Date: | drh 2004-10-02 20:38:28.000 |
Context
2004-10-04
| ||
13:19 | Save about 800 bytes of code space by aligning TK_ and OP_ constants so that we do not have to translate between them. (CVS 1998) (check-in: 4c817e3f29 user: drh tags: trunk) | |
2004-10-02
| ||
20:38 | Fixes to the OsUnlock() interface. Correctly leave a SHARED lock behind when requested. Honor the error code that OsUnlock() returns. Ticket #913 and #938. (CVS 1997) (check-in: c4697503d0 user: drh tags: trunk) | |
2004-10-01
| ||
18:21 | make diskfull test work on Windows; see check-in (1994) (CVS 1996) (check-in: 4493e28780 user: dougcurrie tags: trunk) | |
Changes
Changes to src/os_unix.c.
︙ | ︙ | |||
1017 1018 1019 1020 1021 1022 1023 | /* ** Lower the locking level on file descriptor id to locktype. locktype ** must be either NO_LOCK or SHARED_LOCK. ** ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. ** | | > > > > | | | | | > > > > | 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 | /* ** Lower the locking level on file descriptor id to locktype. locktype ** must be either NO_LOCK or SHARED_LOCK. ** ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. ** ** It is not possible for this routine to fail if the second argument ** is NO_LOCK. If the second argument is SHARED_LOCK, this routine ** might return SQLITE_IOERR instead of SQLITE_OK. */ int sqlite3OsUnlock(OsFile *id, int locktype){ struct lockInfo *pLock; struct flock lock; int rc = SQLITE_OK; assert( id->isOpen ); TRACE7("UNLOCK %d %d was %d(%d,%d) pid=%d\n", id->h, locktype, id->locktype, id->pLock->locktype, id->pLock->cnt, getpid()); assert( locktype<=SHARED_LOCK ); if( id->locktype<=locktype ){ return SQLITE_OK; } sqlite3OsEnterMutex(); pLock = id->pLock; assert( pLock->cnt!=0 ); if( id->locktype>SHARED_LOCK ){ assert( pLock->locktype==id->locktype ); if( locktype==SHARED_LOCK ){ lock.l_type = F_RDLCK; lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST; lock.l_len = SHARED_SIZE; if( fcntl(id->h, F_SETLK, &lock)!=0 ){ /* This should never happen */ rc = SQLITE_IOERR; } } lock.l_type = F_UNLCK; lock.l_whence = SEEK_SET; lock.l_start = PENDING_BYTE; lock.l_len = 2L; assert( PENDING_BYTE+1==RESERVED_BYTE ); fcntl(id->h, F_SETLK, &lock); pLock->locktype = SHARED_LOCK; } |
︙ | ︙ | |||
1083 1084 1085 1086 1087 1088 1089 | sqliteFree(pOpen->aPending); pOpen->nPending = 0; pOpen->aPending = 0; } } sqlite3OsLeaveMutex(); id->locktype = locktype; | | | 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 | sqliteFree(pOpen->aPending); pOpen->nPending = 0; pOpen->aPending = 0; } } sqlite3OsLeaveMutex(); id->locktype = locktype; return rc; } /* ** Close a file. */ int sqlite3OsClose(OsFile *id){ if( !id->isOpen ) return SQLITE_OK; |
︙ | ︙ |
Changes to src/os_win.c.
︙ | ︙ | |||
371 372 373 374 375 376 377 | GetVersionEx(&sInfo); osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; } return osType==2; } /* | | | | | > > > | | 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 | GetVersionEx(&sInfo); osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; } return osType==2; } /* ** Acquire a reader lock. ** Different API routines are called depending on whether or not this ** is Win95 or WinNT. */ static int getReadLock(OsFile *id){ int res; if( isNT() ){ OVERLAPPED ovlp; ovlp.Offset = SHARED_FIRST; ovlp.OffsetHigh = 0; ovlp.hEvent = 0; res = LockFileEx(id->h, LOCKFILE_FAIL_IMMEDIATELY, 0, SHARED_SIZE,0,&ovlp); }else{ int lk; sqlite3Randomness(sizeof(lk), &lk); id->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1); res = LockFile(id->h, SHARED_FIRST+id->sharedLockByte, 0, 1, 0); } return res; } /* ** Undo a readlock */ |
︙ | ︙ | |||
475 476 477 478 479 480 481 | gotPendingLock = res; } /* Acquire a shared lock */ if( locktype==SHARED_LOCK && res ){ assert( id->locktype==NO_LOCK ); | < | < < < < < < | 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 | gotPendingLock = res; } /* Acquire a shared lock */ if( locktype==SHARED_LOCK && res ){ assert( id->locktype==NO_LOCK ); res = getReadLock(id); if( res ){ newLocktype = SHARED_LOCK; } } /* Acquire a RESERVED lock */ |
︙ | ︙ | |||
569 570 571 572 573 574 575 | /* ** Lower the locking level on file descriptor id to locktype. locktype ** must be either NO_LOCK or SHARED_LOCK. ** ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. ** | | > > | > > > > > > | | | 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 | /* ** Lower the locking level on file descriptor id to locktype. locktype ** must be either NO_LOCK or SHARED_LOCK. ** ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. ** ** It is not possible for this routine to fail if the second argument ** is NO_LOCK. If the second argument is SHARED_LOCK then this routine ** might return SQLITE_IOERR; */ int sqlite3OsUnlock(OsFile *id, int locktype){ int type; int rc = SQLITE_OK; assert( id->isOpen ); assert( locktype<=SHARED_LOCK ); TRACE5("UNLOCK %d to %d was %d(%d)\n", id->h, locktype, id->locktype, id->sharedLockByte); type = id->locktype; if( type>=EXCLUSIVE_LOCK ){ UnlockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0); if( locktype==SHARED_LOCK && !getReadLock(id) ){ /* This should never happen. We should always be able to ** reacquire the read lock */ rc = SQLITE_IOERR; } } if( type>=RESERVED_LOCK ){ UnlockFile(id->h, RESERVED_BYTE, 0, 1, 0); } if( locktype==NO_LOCK && type>=SHARED_LOCK ){ unlockReadLock(id); } if( type>=PENDING_LOCK ){ UnlockFile(id->h, PENDING_BYTE, 0, 1, 0); } id->locktype = locktype; return rc; } /* ** 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. */ |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.166 2004/10/02 20:38:28 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include "pager.h" #include <assert.h> #include <string.h> |
︙ | ︙ | |||
751 752 753 754 755 756 757 758 759 760 761 762 763 764 | ** ** TODO: Consider keeping the journal file open for temporary databases. ** This might give a performance improvement on windows where opening ** a file is an expensive operation. */ static int pager_unwritelock(Pager *pPager){ PgHdr *pPg; assert( !pPager->memDb ); if( pPager->state<PAGER_RESERVED ){ return SQLITE_OK; } sqlite3pager_stmt_commit(pPager); if( pPager->stmtOpen ){ sqlite3OsClose(&pPager->stfd); | > | 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 | ** ** TODO: Consider keeping the journal file open for temporary databases. ** This might give a performance improvement on windows where opening ** a file is an expensive operation. */ static int pager_unwritelock(Pager *pPager){ PgHdr *pPg; int rc; assert( !pPager->memDb ); if( pPager->state<PAGER_RESERVED ){ return SQLITE_OK; } sqlite3pager_stmt_commit(pPager); if( pPager->stmtOpen ){ sqlite3OsClose(&pPager->stfd); |
︙ | ︙ | |||
776 777 778 779 780 781 782 | pPg->needSync = 0; } pPager->dirtyCache = 0; pPager->nRec = 0; }else{ assert( pPager->dirtyCache==0 || pPager->useJournal==0 ); } | | | | 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 | pPg->needSync = 0; } pPager->dirtyCache = 0; pPager->nRec = 0; }else{ assert( pPager->dirtyCache==0 || pPager->useJournal==0 ); } rc = sqlite3OsUnlock(&pPager->fd, SHARED_LOCK); pPager->state = PAGER_SHARED; pPager->origDbSize = 0; pPager->setMaster = 0; return rc; } /* ** Compute and return a checksum for the page of data. ** ** This is not a real checksum. It is really just the sum of the ** random initial value and the page number. We experimented with |
︙ | ︙ | |||
2338 2339 2340 2341 2342 2343 2344 | assert( !pPager->memDb ); assert( pPager->state>=PAGER_RESERVED ); assert( pPager->journalOpen==0 ); assert( pPager->useJournal ); sqlite3pager_pagecount(pPager); pPager->aInJournal = sqliteMalloc( pPager->dbSize/8 + 1 ); if( pPager->aInJournal==0 ){ | < < | > < | < < < | 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 | assert( !pPager->memDb ); assert( pPager->state>=PAGER_RESERVED ); assert( pPager->journalOpen==0 ); assert( pPager->useJournal ); sqlite3pager_pagecount(pPager); pPager->aInJournal = sqliteMalloc( pPager->dbSize/8 + 1 ); if( pPager->aInJournal==0 ){ rc = SQLITE_NOMEM; goto failed_to_open_journal; } rc = sqlite3OsOpenExclusive(pPager->zJournal, &pPager->jfd,pPager->tempFile); pPager->journalOff = 0; pPager->setMaster = 0; pPager->journalHdr = 0; if( rc!=SQLITE_OK ){ goto failed_to_open_journal; } sqlite3OsOpenDirectory(pPager->zDirectory, &pPager->jfd); pPager->journalOpen = 1; pPager->journalStarted = 0; pPager->needSync = 0; pPager->alwaysRollback = 0; pPager->nRec = 0; |
︙ | ︙ | |||
2376 2377 2378 2379 2380 2381 2382 | } if( rc!=SQLITE_OK ){ rc = pager_unwritelock(pPager); if( rc==SQLITE_OK ){ rc = SQLITE_FULL; } } | | > > > > > > > | 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 | } if( rc!=SQLITE_OK ){ rc = pager_unwritelock(pPager); if( rc==SQLITE_OK ){ rc = SQLITE_FULL; } } return rc; failed_to_open_journal: sqliteFree(pPager->aInJournal); pPager->aInJournal = 0; sqlite3OsUnlock(&pPager->fd, NO_LOCK); pPager->state = PAGER_UNLOCK; return rc; } /* ** Acquire a write-lock on the database. The lock is removed when ** the any of the following happen: ** ** * sqlite3pager_commit() is called. |
︙ | ︙ |