Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Change prototype for busy callbacks to "int xBusy(void *, int);" (CVS 1573) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
4f1cfca5ca703d0068cf8d6222dc8e0c |
User & Date: | danielk1977 2004-06-12 01:43:26.000 |
Context
2004-06-12
| ||
02:17 | Bug fix in the unix locking code. (CVS 1574) (check-in: dcad244f58 user: drh tags: trunk) | |
01:43 | Change prototype for busy callbacks to "int xBusy(void *, int);" (CVS 1573) (check-in: 4f1cfca5ca user: danielk1977 tags: trunk) | |
00:42 | Use the SQLITE_UTF* symbols instead of the old internal TEXT_Utf* symbols. (CVS 1572) (check-in: 9b84f2f488 user: danielk1977 tags: trunk) | |
Changes
Changes to src/main.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** ** $Id: main.c,v 1.217 2004/06/12 01:43:26 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** A pointer to this structure is used to communicate information |
︙ | ︙ | |||
604 605 606 607 608 609 610 | /* ** This routine sets the busy callback for an Sqlite database to the ** given callback function with the given argument. */ void sqlite3_busy_handler( sqlite *db, | | | 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 | /* ** This routine sets the busy callback for an Sqlite database to the ** given callback function with the given argument. */ void sqlite3_busy_handler( sqlite *db, int (*xBusy)(void*,int), void *pArg ){ db->busyHandler.xFunc = xBusy; db->busyHandler.pArg = pArg; } #ifndef SQLITE_OMIT_PROGRESS_CALLBACK |
︙ | ︙ |
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.124 2004/06/12 01:43:26 danielk1977 Exp $ */ #include "os.h" /* Must be first to enable large file support */ #include "sqliteInt.h" #include "pager.h" #include <assert.h> #include <string.h> |
︙ | ︙ | |||
1551 1552 1553 1554 1555 1556 1557 | ** will require a journal playback. */ do { rc = sqlite3OsLock(&pPager->fd, EXCLUSIVE_LOCK); }while( rc==SQLITE_BUSY && pPager->pBusyHandler && pPager->pBusyHandler->xFunc && | | | 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 | ** will require a journal playback. */ do { rc = sqlite3OsLock(&pPager->fd, EXCLUSIVE_LOCK); }while( rc==SQLITE_BUSY && pPager->pBusyHandler && pPager->pBusyHandler->xFunc && pPager->pBusyHandler->xFunc(pPager->pBusyHandler->pArg, busy++) ); if( rc!=SQLITE_OK ){ return rc; } pPager->state = PAGER_EXCLUSIVE; while( pList ){ |
︙ | ︙ | |||
1635 1636 1637 1638 1639 1640 1641 | if( pPager->nRef==0 && !pPager->memDb ){ int busy = 1; do { rc = sqlite3OsLock(&pPager->fd, SHARED_LOCK); }while( rc==SQLITE_BUSY && pPager->pBusyHandler && pPager->pBusyHandler->xFunc && | | | 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 | if( pPager->nRef==0 && !pPager->memDb ){ int busy = 1; do { rc = sqlite3OsLock(&pPager->fd, SHARED_LOCK); }while( rc==SQLITE_BUSY && pPager->pBusyHandler && pPager->pBusyHandler->xFunc && pPager->pBusyHandler->xFunc(pPager->pBusyHandler->pArg, busy++) ); if( rc!=SQLITE_OK ){ return rc; } pPager->state = PAGER_SHARED; /* If a journal file exists, and there is no RESERVED lock on the |
︙ | ︙ | |||
2026 2027 2028 2029 2030 2031 2032 | }else{ int busy = 1; do { rc = sqlite3OsLock(&pPager->fd, RESERVED_LOCK); }while( rc==SQLITE_BUSY && pPager->pBusyHandler && pPager->pBusyHandler->xFunc && | | | 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 | }else{ int busy = 1; do { rc = sqlite3OsLock(&pPager->fd, RESERVED_LOCK); }while( rc==SQLITE_BUSY && pPager->pBusyHandler && pPager->pBusyHandler->xFunc && pPager->pBusyHandler->xFunc(pPager->pBusyHandler->pArg, busy++) ); if( rc!=SQLITE_OK ){ return rc; } pPager->nMaster = nMaster; pPager->state = PAGER_RESERVED; pPager->dirtyCache = 0; |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** ** @(#) $Id: sqlite.h.in,v 1.100 2004/06/12 01:43:27 danielk1977 Exp $ */ #ifndef _SQLITE_H_ #define _SQLITE_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** Make sure we can call this stuff from C++. |
︙ | ︙ | |||
238 239 240 241 242 243 244 | ** Sqlite is re-entrant, so the busy handler may start a new query. ** (It is not clear why anyone would every want to do this, but it ** is allowed, in theory.) But the busy handler may not close the ** database. Closing the database from a busy handler will delete ** data structures out from under the executing query and will ** probably result in a coredump. */ | | | 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | ** Sqlite is re-entrant, so the busy handler may start a new query. ** (It is not clear why anyone would every want to do this, but it ** is allowed, in theory.) But the busy handler may not close the ** database. Closing the database from a busy handler will delete ** data structures out from under the executing query and will ** probably result in a coredump. */ void sqlite3_busy_handler(sqlite*, int(*)(void*,int), void*); /* ** This routine sets a busy handler that sleeps for a while when a ** table is locked. The handler will sleep multiple times until ** at least "ms" milleseconds of sleeping have been done. After ** "ms" milleseconds of sleeping, the handler returns 0 which ** causes sqlite3_exec() to return SQLITE_BUSY. |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.284 2004/06/12 01:43:27 danielk1977 Exp $ */ #include "config.h" #include "sqlite3.h" #include "hash.h" #include "parse.h" #include <stdio.h> #include <stdlib.h> |
︙ | ︙ | |||
338 339 340 341 342 343 344 | ** ** The sqlite.busyHandler member of the sqlite struct contains the busy ** callback for the database handle. Each pager opened via the sqlite ** handle is passed a pointer to sqlite.busyHandler. The busy-handler ** callback is currently invoked only from within pager.c. */ struct BusyHandler { | | | | 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 | ** ** The sqlite.busyHandler member of the sqlite struct contains the busy ** callback for the database handle. Each pager opened via the sqlite ** handle is passed a pointer to sqlite.busyHandler. The busy-handler ** callback is currently invoked only from within pager.c. */ struct BusyHandler { int (*xFunc)(void *,int); /* The busy callback */ void *pArg; /* First arg to busy callback */ }; /* ** Each database is an instance of the following structure. ** ** The sqlite.temp_store determines where temporary database files ** are stored. If 1, then a file is created to hold those tables. If |
︙ | ︙ |
Changes to src/tclsqlite.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** A TCL Interface to SQLite ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** A TCL Interface to SQLite ** ** $Id: tclsqlite.c,v 1.84 2004/06/12 01:43:27 danielk1977 Exp $ */ #ifndef NO_TCL /* Omit this whole file if TCL is unavailable */ #include "sqliteInt.h" #include "tcl.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
145 146 147 148 149 150 151 | Tcl_Free((char*)pDb); } /* ** This routine is called when a database file is locked while trying ** to execute SQL. */ | | < | | | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | Tcl_Free((char*)pDb); } /* ** This routine is called when a database file is locked while trying ** to execute SQL. */ static int DbBusyHandler(void *cd, int nTries){ SqliteDb *pDb = (SqliteDb*)cd; int rc; char zVal[30]; char *zCmd; Tcl_DString cmd; Tcl_DStringInit(&cmd); Tcl_DStringAppend(&cmd, pDb->zBusy, -1); sprintf(zVal, "%d", nTries); Tcl_DStringAppendElement(&cmd, zVal); zCmd = Tcl_DStringValue(&cmd); rc = Tcl_Eval(pDb->interp, zCmd); Tcl_DStringFree(&cmd); if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){ return 0; } return 1; |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.367 2004/06/12 01:43:27 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
2374 2375 2376 2377 2378 2379 2380 | if( pBt ){ if( db->nMaster<0 ){ db->nMaster = strlen(sqlite3BtreeGetFilename(db->aDb[0].pBt))+20; } rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, db->nMaster); if( rc==SQLITE_BUSY ){ | < | | | | < < | < | | 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 | if( pBt ){ if( db->nMaster<0 ){ db->nMaster = strlen(sqlite3BtreeGetFilename(db->aDb[0].pBt))+20; } rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, db->nMaster); if( rc==SQLITE_BUSY ){ p->pc = pc; p->rc = SQLITE_BUSY; p->pTos = pTos; return SQLITE_BUSY; } if( rc!=SQLITE_OK && rc!=SQLITE_READONLY /* && rc!=SQLITE_BUSY */ ){ goto abort_due_to_error; } } break; } /* Opcode: ReadCookie P1 P2 * |
︙ | ︙ | |||
2561 2562 2563 2564 2565 2566 2567 | pCur->pIncrKey = &pCur->pKeyInfo->incrKey; pCur->pKeyInfo->enc = p->db->enc; }else{ pCur->pIncrKey = &pCur->bogusIncrKey; } switch( rc ){ case SQLITE_BUSY: { | < | | | | < < < < | 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 | pCur->pIncrKey = &pCur->pKeyInfo->incrKey; pCur->pKeyInfo->enc = p->db->enc; }else{ pCur->pIncrKey = &pCur->bogusIncrKey; } switch( rc ){ case SQLITE_BUSY: { p->pc = pc; p->rc = SQLITE_BUSY; p->pTos = &pTos[1 + (pOp->p2<=0)]; /* Operands must remain on stack */ return SQLITE_BUSY; } case SQLITE_OK: { int flags = sqlite3BtreeFlags(pCur->pCursor); pCur->intKey = (flags & BTREE_INTKEY)!=0; pCur->zeroData = (flags & BTREE_ZERODATA)!=0; break; } |
︙ | ︙ |
Changes to test/lock.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2001 September 15 # # 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 database locks. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2001 September 15 # # 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 database locks. # # $Id: lock.test,v 1.24 2004/06/12 01:43:27 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Create an alternative connection to the database # |
︙ | ︙ | |||
168 169 170 171 172 173 174 | catchsql {SELECT * FROM t2} db2 } {0 {9 8}} # If the other thread (the one that does not hold the transaction with # a RESERVED lock) tries to get a RESERVED lock, we get a busy callback. # do_test lock-2.3 { | | | | | | | | | 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 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 | catchsql {SELECT * FROM t2} db2 } {0 {9 8}} # If the other thread (the one that does not hold the transaction with # a RESERVED lock) tries to get a RESERVED lock, we get a busy callback. # do_test lock-2.3 { proc callback {count} { set ::callback_value $count break } set ::callback_value {} db2 busy callback set r [catch {execsql {UPDATE t1 SET a=b, b=a} db2} msg] lappend r $msg lappend r $::callback_value } {1 {database is locked} 1} do_test lock-2.4 { proc callback {count} { lappend ::callback_value $count if {$count>4} break } set ::callback_value {} db2 busy callback set r [catch {execsql {UPDATE t1 SET a=b, b=a} db2} msg] lappend r $msg lappend r $::callback_value } {1 {database is locked} {1 2 3 4 5}} do_test lock-2.5 { proc callback {count} { lappend ::callback_value $count if {$count>4} break } set ::callback_value {} db2 busy callback set r [catch {execsql {SELECT * FROM t1} db2} msg] lappend r $msg lappend r $::callback_value } {0 {2 1} {}} # In this test, the 3rd invocation of the busy callback causes # the first thread to release its transaction. That allows the # second thread to continue. # do_test lock-2.6 { proc callback {count} { lappend ::callback_value $count if {$count>2} { execsql {ROLLBACK} } } set ::callback_value {} db2 busy callback set r [catch {execsql {SELECT * FROM t2} db2} msg] lappend r $msg lappend r $::callback_value } {0 {9 8} {}} do_test lock-2.7 { proc callback {count} { lappend ::callback_value $count if {$count>2} { execsql {ROLLBACK} } } set ::callback_value {} db2 busy callback |
︙ | ︙ | |||
277 278 279 280 281 282 283 | } {1 {database is locked}} do_test lock-4.2 { set ::callback_value {} set rc [catch {db2 eval {UPDATE t1 SET a=0}} msg] lappend rc $msg $::callback_value } {1 {database is locked} {}} do_test lock-4.3 { | | | 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | } {1 {database is locked}} do_test lock-4.2 { set ::callback_value {} set rc [catch {db2 eval {UPDATE t1 SET a=0}} msg] lappend rc $msg $::callback_value } {1 {database is locked} {}} do_test lock-4.3 { proc callback {count} { lappend ::callback_value $count if {$count>4} break } db2 busy callback set rc [catch {db2 eval {UPDATE t1 SET a=0}} msg] lappend rc $msg $::callback_value } {1 {database is locked} {1 2 3 4 5}} |
︙ | ︙ |
Changes to test/threadtest1.c.
︙ | ︙ | |||
43 44 45 46 47 48 49 | extern char *sqlite_mprintf(const char *zFormat, ...); extern char *sqlite_vmprintf(const char *zFormat, va_list); /* ** When a lock occurs, yield. */ | | | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | extern char *sqlite_mprintf(const char *zFormat, ...); extern char *sqlite_vmprintf(const char *zFormat, va_list); /* ** When a lock occurs, yield. */ static int db_is_locked(void *NotUsed, int iNotUsed){ /* sched_yield(); */ if( verbose ) printf("BUSY %s\n", (char*)NotUsed); usleep(100); return 1; } /* |
︙ | ︙ |