Index: third_party/sqlite/src/src/test7.c |
diff --git a/third_party/sqlite/src/src/test7.c b/third_party/sqlite/src/src/test7.c |
index 852cd1db5e849f422180022cc41e7e00ac7de0ef..93bf1e4898b004ce10dc131a1f4258b8a3f20aaf 100644 |
--- a/third_party/sqlite/src/src/test7.c |
+++ b/third_party/sqlite/src/src/test7.c |
@@ -40,6 +40,7 @@ int sqlite3_client_finalize(sqlite3_stmt*); |
int sqlite3_client_close(sqlite3*); |
int sqlite3_server_start(void); |
int sqlite3_server_stop(void); |
+void sqlite3_server_start2(int *pnDecr); |
/* |
** Each thread is controlled by an instance of the following |
@@ -68,6 +69,13 @@ struct Thread { |
int argc; /* number of columns in result */ |
const char *argv[100]; /* result columns */ |
const char *colv[100]; /* result column names */ |
+ |
+ /* Initialized to 1 by the supervisor thread when the client is |
+ ** created, and then deemed read-only to the supervisor thread. |
+ ** Is set to 0 by the server thread belonging to this client |
+ ** just before it exits. |
+ */ |
+ int nServer; /* Number of server threads running */ |
}; |
/* |
@@ -175,7 +183,10 @@ static int tcl_client_create( |
return TCL_ERROR; |
} |
pthread_detach(x); |
- sqlite3_server_start(); |
+ if( threadset[i].nServer==0 ){ |
+ threadset[i].nServer = 1; |
+ sqlite3_server_start2(&threadset[i].nServer); |
+ } |
return TCL_OK; |
} |
@@ -268,6 +279,11 @@ static int tcl_client_halt( |
for(i=0; i<N_THREAD && threadset[i].busy==0; i++){} |
if( i>=N_THREAD ){ |
sqlite3_server_stop(); |
+ while( 1 ){ |
+ for(i=0; i<N_THREAD && threadset[i].nServer==0; i++); |
+ if( i==N_THREAD ) break; |
+ sched_yield(); |
+ } |
} |
return TCL_OK; |
} |
@@ -376,6 +392,8 @@ static int tcl_client_colname( |
return TCL_OK; |
} |
+extern const char *sqlite3ErrName(int); |
+ |
/* |
** Usage: client_result ID |
** |
@@ -403,34 +421,7 @@ static int tcl_client_result( |
return TCL_ERROR; |
} |
client_wait(&threadset[i]); |
- switch( threadset[i].rc ){ |
- case SQLITE_OK: zName = "SQLITE_OK"; break; |
- case SQLITE_ERROR: zName = "SQLITE_ERROR"; break; |
- case SQLITE_PERM: zName = "SQLITE_PERM"; break; |
- case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; |
- case SQLITE_BUSY: zName = "SQLITE_BUSY"; break; |
- case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break; |
- case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; |
- case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; |
- case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; |
- case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; |
- case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; |
- case SQLITE_FULL: zName = "SQLITE_FULL"; break; |
- case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; |
- case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; |
- case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; |
- case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break; |
- case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break; |
- case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break; |
- case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break; |
- case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break; |
- case SQLITE_AUTH: zName = "SQLITE_AUTH"; break; |
- case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break; |
- case SQLITE_RANGE: zName = "SQLITE_RANGE"; break; |
- case SQLITE_ROW: zName = "SQLITE_ROW"; break; |
- case SQLITE_DONE: zName = "SQLITE_DONE"; break; |
- default: zName = "SQLITE_Unknown"; break; |
- } |
+ zName = sqlite3ErrName(threadset[i].rc); |
Tcl_AppendResult(interp, zName, 0); |
return TCL_OK; |
} |