Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a segfault in sqlite3OsLock() (CVS 1525) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
51348b82c4d5801091537b80059d7704 |
User & Date: | danielk1977 2004-06-02 06:30:16.000 |
Context
2004-06-03
| ||
16:08 | Untested updates to support atomic multi-file transactions (CVS 1526) (check-in: d57e5252c8 user: danielk1977 tags: trunk) | |
2004-06-02
| ||
06:30 | Fix a segfault in sqlite3OsLock() (CVS 1525) (check-in: 51348b82c4 user: danielk1977 tags: trunk) | |
01:22 | Work toward combining the OP_MakeKey, OP_MakeIdxKey, and OP_MakeRecord opcodes into one. The work is incomplete. (CVS 1524) (check-in: 165d69a04c user: drh tags: trunk) | |
Changes
Changes to src/os_unix.c.
︙ | ︙ | |||
57 58 59 60 61 62 63 | /* ** Include code that is common to all os_*.c files */ #include "os_common.h" | < | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | /* ** Include code that is common to all os_*.c files */ #include "os_common.h" /* ** Here is the dirt on POSIX advisory locks: ANSI STD 1003.1 (1996) ** section 6.5.2.2 lines 483 through 490 specify that when a process ** sets or clears a lock, that operation overrides any prior locks set ** by the same process. It does not explicitly say so, but this implies ** that it overrides locks set by the same process using a different ** file descriptor. Consider this test case: |
︙ | ︙ | |||
645 646 647 648 649 650 651 | ** If the file was read locked, then this acquires a new read lock. ** ** Return SQLITE_OK on success and SQLITE_BUSY on failure. 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 sqlite3OsReadLock(OsFile *id){ | < < | 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 | ** If the file was read locked, then this acquires a new read lock. ** ** Return SQLITE_OK on success and SQLITE_BUSY on failure. 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 sqlite3OsReadLock(OsFile *id){ return sqlite3OsLock(id, SHARED_LOCK); } /* ** Change the lock status to be an exclusive or write lock. Return ** SQLITE_OK on success and SQLITE_BUSY on a failure. 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 sqlite3OsWriteLock(OsFile *id){ return sqlite3OsLock(id, EXCLUSIVE_LOCK); } /* ** Lock the file with the lock specified by parameter locktype - one ** of the following: ** |
︙ | ︙ | |||
711 712 713 714 715 716 717 718 719 720 721 722 723 | ** has a SHARED or RESERVED lock, then increment reference counts and ** return SQLITE_OK. */ if( locktype==SHARED_LOCK && (pLock->locktype==SHARED_LOCK || pLock->locktype==RESERVED_LOCK) ){ assert( locktype==SHARED_LOCK ); assert( id->locked==0 ); id->locked = SHARED_LOCK; pLock->cnt++; id->pOpen->nLock++; goto end_lock; } | > | < | 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 | ** has a SHARED or RESERVED lock, then increment reference counts and ** return SQLITE_OK. */ if( locktype==SHARED_LOCK && (pLock->locktype==SHARED_LOCK || pLock->locktype==RESERVED_LOCK) ){ assert( locktype==SHARED_LOCK ); assert( id->locked==0 ); assert( pLock->cnt>0 ); id->locked = SHARED_LOCK; pLock->cnt++; id->pOpen->nLock++; goto end_lock; } lock.l_len = 0L; lock.l_whence = SEEK_SET; /* If control gets to this point, then actually go ahead and make ** operating system calls for the specified lock. */ if( locktype==SHARED_LOCK ){ assert( pLock->cnt==0 ); assert( pLock->locktype==0 ); /* Grab a read-lock on byte 2. This ensures that no other process ** has a PENDING lock. */ lock.l_type = F_RDLCK; lock.l_start = 2; |
︙ | ︙ | |||
749 750 751 752 753 754 755 | lock.l_start = 2; lock.l_type = F_UNLCK; fcntl(id->fd, F_SETLK, &lock); if( s ){ rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY; }else{ id->locked = SHARED_LOCK; | | | 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 | lock.l_start = 2; lock.l_type = F_UNLCK; fcntl(id->fd, F_SETLK, &lock); if( s ){ rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY; }else{ id->locked = SHARED_LOCK; id->pOpen->nLock++; pLock->cnt = 1; } }else{ /* The request was for a RESERVED, PENDING or EXCLUSIVE lock. It is ** assumed that there is a SHARED or greater lock on the file ** already. */ |
︙ | ︙ | |||
778 779 780 781 782 783 784 | } s = fcntl(id->fd, F_SETLK, &lock); if( s ){ rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY; } } | > | | | > > < < > | 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 | } s = fcntl(id->fd, F_SETLK, &lock); if( s ){ rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY; } } if( rc==SQLITE_OK ){ id->locked = locktype; pLock->locktype = locktype; assert( pLock->locktype==RESERVED_LOCK || pLock->cnt==1 ); } end_lock: sqlite3OsLeaveMutex(); return rc; } /* ** 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 sqlite3OsUnlock(OsFile *id){ int rc; if( !id->locked ) return SQLITE_OK; id->locked = 0; sqlite3OsEnterMutex(); 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; id->pLock->locktype = 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--; |
︙ | ︙ |
Changes to test/thread1.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2003 December 18 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is multithreading behavior # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2003 December 18 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is multithreading behavior # # $Id: thread1.test,v 1.4 2004/06/02 06:30:18 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Skip this whole file if the thread testing code is not enabled # |
︙ | ︙ | |||
143 144 145 146 147 148 149 | thread_result B } SQLITE_OK do_test thread1-2.9 { thread_step C thread_result C } SQLITE_DONE do_test thread1-2.10 { | < < < > > > | 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | thread_result B } SQLITE_OK do_test thread1-2.9 { thread_step C thread_result C } SQLITE_DONE do_test thread1-2.10 { thread_finalize C thread_result C } SQLITE_OK do_test thread1-2.11 { execsql {SELECT * FROM t2} } {98 99} thread_halt * finish_test |