Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a memory leak that can occur in os_unix.c if an IO error occurs within the xUnlock method. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
6c5c04eea1f0e8d61883ee8675c249fb |
User & Date: | dan 2010-06-16 10:55:43.000 |
Context
2010-06-16
| ||
12:30 | Add extra test cases to pager1.test. (check-in: ad3209572d user: dan tags: trunk) | |
10:55 | Fix a memory leak that can occur in os_unix.c if an IO error occurs within the xUnlock method. (check-in: 6c5c04eea1 user: dan tags: trunk) | |
2010-06-15
| ||
19:07 | Rationalize a common pattern in tcl test cases into proc do_multiclient_test. (check-in: efe4456498 user: dan tags: trunk) | |
Changes
Changes to src/os_unix.c.
︙ | |||
730 731 732 733 734 735 736 737 738 739 740 741 742 743 | 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + | #endif }; /* ** A lists of all unixInodeInfo objects. */ static unixInodeInfo *inodeList = 0; /* ** Close all file descriptors accumuated in the unixInodeInfo->pUnused list. ** If all such file descriptors are closed without error, the list is ** cleared and SQLITE_OK returned. ** ** Otherwise, if an error occurs, then successfully closed file descriptor ** entries are removed from the list, and SQLITE_IOERR_CLOSE returned. ** not deleted and SQLITE_IOERR_CLOSE returned. */ static int closePendingFds(unixFile *pFile){ int rc = SQLITE_OK; unixInodeInfo *pInode = pFile->pInode; UnixUnusedFd *pError = 0; UnixUnusedFd *p; UnixUnusedFd *pNext; for(p=pInode->pUnused; p; p=pNext){ pNext = p->pNext; if( close(p->fd) ){ pFile->lastErrno = errno; rc = SQLITE_IOERR_CLOSE; p->pNext = pError; pError = p; }else{ sqlite3_free(p); } } pInode->pUnused = pError; return rc; } /* ** Release a unixInodeInfo structure previously allocated by findInodeInfo(). ** ** The mutex entered using the unixEnterMutex() function must be held ** when this function is called. */ |
︙ | |||
1148 1149 1150 1151 1152 1153 1154 | 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | end_lock: unixLeaveMutex(); OSTRACE(("LOCK %d %s %s (unix)\n", pFile->h, azFileLock(eFileLock), rc==SQLITE_OK ? "ok" : "failed")); return rc; } |
︙ | |||
1447 1448 1449 1450 1451 1452 1453 | 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 | - + | /* If there are outstanding locks, do not actually close the file just ** yet because that would clear those locks. Instead, add the file ** descriptor to pInode->pUnused list. It will be automatically closed ** when the last lock is cleared. */ setPendingFd(pFile); } |
︙ | |||
2062 2063 2064 2065 2066 2067 2068 | 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 | - + | */ static int semClose(sqlite3_file *id) { if( id ){ unixFile *pFile = (unixFile*)id; semUnlock(id, NO_LOCK); assert( pFile ); unixEnterMutex(); |
︙ | |||
2529 2530 2531 2532 2533 2534 2535 | 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 | - + | /* If there are outstanding locks, do not actually close the file just ** yet because that would clear those locks. Instead, add the file ** descriptor to pInode->aPending. It will be automatically closed when ** the last lock is cleared. */ setPendingFd(pFile); } |
︙ |
Changes to src/test_vfs.c.
︙ | |||
72 73 74 75 76 77 78 | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | + - + | #define TESTVFS_SHMLOCK_MASK 0x00000010 #define TESTVFS_SHMMAP_MASK 0x00000020 #define TESTVFS_SHMBARRIER_MASK 0x00000040 #define TESTVFS_SHMCLOSE_MASK 0x00000080 #define TESTVFS_OPEN_MASK 0x00000100 #define TESTVFS_SYNC_MASK 0x00000200 #define TESTVFS_DELETE_MASK 0x00000400 |
︙ | |||
453 454 455 456 457 458 459 | 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 | + + + + + + + + + + - + + + | /* ** Delete the file located at zPath. If the dirSync argument is true, ** ensure the file-system modifications are synced to disk before ** returning. */ static int tvfsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ int rc = SQLITE_OK; Testvfs *p = (Testvfs *)pVfs->pAppData; if( p->pScript && p->mask&TESTVFS_DELETE_MASK ){ tvfsExecTcl(p, "xDelete", Tcl_NewStringObj(zPath, -1), Tcl_NewIntObj(dirSync), 0 ); tvfsResultCode(p, &rc); } if( rc==SQLITE_OK ){ |
︙ | |||
839 840 841 842 843 844 845 846 847 848 849 850 851 852 | 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 | + | } vfsmethod [] = { { "xShmOpen", TESTVFS_SHMOPEN_MASK }, { "xShmLock", TESTVFS_SHMLOCK_MASK }, { "xShmBarrier", TESTVFS_SHMBARRIER_MASK }, { "xShmClose", TESTVFS_SHMCLOSE_MASK }, { "xShmMap", TESTVFS_SHMMAP_MASK }, { "xSync", TESTVFS_SYNC_MASK }, { "xDelete", TESTVFS_DELETE_MASK }, { "xOpen", TESTVFS_OPEN_MASK }, }; Tcl_Obj **apElem = 0; int nElem = 0; int i; int mask = 0; if( objc!=3 ){ |
︙ |
Changes to test/malloc_common.tcl.
︙ | |||
105 106 107 108 109 110 111 112 113 114 | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | + + - - - + + + - - - + - - + - - - - + + + + - - - + + + - - - - + - - - - + | eval do_one_faultsim_test "$name-$f" $FAULTSIM($f) $testspec } } #------------------------------------------------------------------------- # Procedures to save and restore the current file-system state: # # faultsim_save # faultsim_save_and_close # faultsim_restore_and_reopen # faultsim_delete_and_reopen # |
︙ |
Changes to test/pager1.test.
︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | + + + + + + + + + + + + + + + | #*********************************************************************** # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl source $testdir/malloc_common.tcl # # pager1-1.*: Test inter-process locking (clients in multiple processes). # # pager1-2.*: Test intra-process locking (multiple clients in this process). # # pager1-3.*: Savepoint related tests. # proc do_execsql_test {testname sql result} { uplevel do_test $testname [list "execsql {$sql}"] [list $result] } proc do_catchsql_test {testname sql result} { uplevel do_test $testname [list "catchsql {$sql}"] [list $result] } do_multiclient_test tn { # Create and populate a database table using connection [db]. Check # that connections [db2] and [db3] can see the schema and content. # do_test pager1-$tn.1 { |
︙ | |||
147 148 149 150 151 152 153 154 155 | 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | do_test pager1-$tn.25 { sql1 { UPDATE t1 SET a = a+10 } } {} do_test pager1-$tn.26 { sql1 { COMMIT } } {} do_test pager1-$tn.27 { sql1 { SELECT * FROM t1 } } {21 one 22 two 23 three} do_test pager1-$tn.27 { sql2 { SELECT * FROM t1 } } {21 one 22 two 23 three} do_test pager1-$tn.28 { sql3 { SELECT * FROM t1 } } {21 one 22 two 23 three} } do_test pager1-3.1 { faultsim_delete_and_reopen execsql { CREATE TABLE t1(a PRIMARY KEY, b); CREATE TABLE counter( i CHECK (i<5), u CHECK (u<10) ); INSERT INTO counter VALUES(0, 0); CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN UPDATE counter SET i = i+1; END; CREATE TRIGGER tr2 AFTER UPDATE ON t1 BEGIN UPDATE counter SET u = u+1; END; } execsql { SELECT * FROM counter } } {0 0} do_execsql_test pager1-3.2 { BEGIN; INSERT INTO t1 VALUES(1, randomblob(1500)); INSERT INTO t1 VALUES(2, randomblob(1500)); INSERT INTO t1 VALUES(3, randomblob(1500)); SELECT * FROM counter; } {3 0} do_catchsql_test pager1-3.3 { INSERT INTO t1 SELECT a+3, randomblob(1500) FROM t1 } {1 {constraint failed}} do_execsql_test pager1-3.4 { SELECT * FROM counter } {3 0} do_execsql_test pager1-3.5 { SELECT a FROM t1 } {1 2 3} do_execsql_test pager1-3.6 { COMMIT } {} finish_test |
Added test/pagerfault.test.