OLD | NEW |
1 /* | 1 /* |
2 ** 2003 December 18 | 2 ** 2003 December 18 |
3 ** | 3 ** |
4 ** The author disclaims copyright to this source code. In place of | 4 ** The author disclaims copyright to this source code. In place of |
5 ** a legal notice, here is a blessing: | 5 ** a legal notice, here is a blessing: |
6 ** | 6 ** |
7 ** May you do good and not evil. | 7 ** May you do good and not evil. |
8 ** May you find forgiveness for yourself and forgive others. | 8 ** May you find forgiveness for yourself and forgive others. |
9 ** May you share freely, never taking more than you give. | 9 ** May you share freely, never taking more than you give. |
10 ** | 10 ** |
11 ************************************************************************* | 11 ************************************************************************* |
12 ** Code for testing the the SQLite library in a multithreaded environment. | 12 ** Code for testing the SQLite library in a multithreaded environment. |
13 */ | 13 */ |
14 #include "sqliteInt.h" | 14 #include "sqliteInt.h" |
15 #include "tcl.h" | 15 #include "tcl.h" |
16 #if SQLITE_OS_UNIX && SQLITE_THREADSAFE | 16 #if SQLITE_OS_UNIX && SQLITE_THREADSAFE |
17 #include <stdlib.h> | 17 #include <stdlib.h> |
18 #include <string.h> | 18 #include <string.h> |
19 #include <pthread.h> | 19 #include <pthread.h> |
20 #include <sched.h> | 20 #include <sched.h> |
21 #include <ctype.h> | 21 #include <ctype.h> |
22 | 22 |
| 23 extern const char *sqlite3ErrName(int); |
| 24 |
23 /* | 25 /* |
24 ** Each thread is controlled by an instance of the following | 26 ** Each thread is controlled by an instance of the following |
25 ** structure. | 27 ** structure. |
26 */ | 28 */ |
27 typedef struct Thread Thread; | 29 typedef struct Thread Thread; |
28 struct Thread { | 30 struct Thread { |
29 /* The first group of fields are writable by the master and read-only | 31 /* The first group of fields are writable by the master and read-only |
30 ** to the thread. */ | 32 ** to the thread. */ |
31 char *zFilename; /* Name of database file */ | 33 char *zFilename; /* Name of database file */ |
32 void (*xOp)(Thread*); /* next operation to do */ | 34 void (*xOp)(Thread*); /* next operation to do */ |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 " ID", 0); | 367 " ID", 0); |
366 return TCL_ERROR; | 368 return TCL_ERROR; |
367 } | 369 } |
368 i = parse_thread_id(interp, argv[1]); | 370 i = parse_thread_id(interp, argv[1]); |
369 if( i<0 ) return TCL_ERROR; | 371 if( i<0 ) return TCL_ERROR; |
370 if( !threadset[i].busy ){ | 372 if( !threadset[i].busy ){ |
371 Tcl_AppendResult(interp, "no such thread", 0); | 373 Tcl_AppendResult(interp, "no such thread", 0); |
372 return TCL_ERROR; | 374 return TCL_ERROR; |
373 } | 375 } |
374 thread_wait(&threadset[i]); | 376 thread_wait(&threadset[i]); |
375 switch( threadset[i].rc ){ | 377 zName = sqlite3ErrName(threadset[i].rc); |
376 case SQLITE_OK: zName = "SQLITE_OK"; break; | |
377 case SQLITE_ERROR: zName = "SQLITE_ERROR"; break; | |
378 case SQLITE_PERM: zName = "SQLITE_PERM"; break; | |
379 case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; | |
380 case SQLITE_BUSY: zName = "SQLITE_BUSY"; break; | |
381 case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break; | |
382 case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; | |
383 case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; | |
384 case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; | |
385 case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; | |
386 case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; | |
387 case SQLITE_FULL: zName = "SQLITE_FULL"; break; | |
388 case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; | |
389 case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; | |
390 case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; | |
391 case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break; | |
392 case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break; | |
393 case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break; | |
394 case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break; | |
395 case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break; | |
396 case SQLITE_AUTH: zName = "SQLITE_AUTH"; break; | |
397 case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break; | |
398 case SQLITE_RANGE: zName = "SQLITE_RANGE"; break; | |
399 case SQLITE_ROW: zName = "SQLITE_ROW"; break; | |
400 case SQLITE_DONE: zName = "SQLITE_DONE"; break; | |
401 default: zName = "SQLITE_Unknown"; break; | |
402 } | |
403 Tcl_AppendResult(interp, zName, 0); | 378 Tcl_AppendResult(interp, zName, 0); |
404 return TCL_OK; | 379 return TCL_OK; |
405 } | 380 } |
406 | 381 |
407 /* | 382 /* |
408 ** Usage: thread_error ID | 383 ** Usage: thread_error ID |
409 ** | 384 ** |
410 ** Wait on the most recent operation to complete, then return the | 385 ** Wait on the most recent operation to complete, then return the |
411 ** error string. | 386 ** error string. |
412 */ | 387 */ |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 int i; | 713 int i; |
739 | 714 |
740 for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ | 715 for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ |
741 Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); | 716 Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); |
742 } | 717 } |
743 return TCL_OK; | 718 return TCL_OK; |
744 } | 719 } |
745 #else | 720 #else |
746 int Sqlitetest4_Init(Tcl_Interp *interp){ return TCL_OK; } | 721 int Sqlitetest4_Init(Tcl_Interp *interp){ return TCL_OK; } |
747 #endif /* SQLITE_OS_UNIX */ | 722 #endif /* SQLITE_OS_UNIX */ |
OLD | NEW |