| OLD | NEW |
| 1 /* | 1 /* |
| 2 ** 2005 December 14 | 2 ** 2005 December 14 |
| 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 ** | 12 ** |
| 13 ** This file contains a binding of the asynchronous IO extension interface | 13 ** This file contains a binding of the asynchronous IO extension interface |
| 14 ** (defined in ext/async/sqlite3async.h) to Tcl. | 14 ** (defined in ext/async/sqlite3async.h) to Tcl. |
| 15 */ | 15 */ |
| 16 | 16 |
| 17 #define TCL_THREADS | 17 #define TCL_THREADS |
| 18 #include <tcl.h> | 18 #if defined(INCLUDE_SQLITE_TCL_H) |
| 19 # include "sqlite_tcl.h" |
| 20 #else |
| 21 # include "tcl.h" |
| 22 # ifndef SQLITE_TCLAPI |
| 23 # define SQLITE_TCLAPI |
| 24 # endif |
| 25 #endif |
| 19 | 26 |
| 20 #ifdef SQLITE_ENABLE_ASYNCIO | 27 #ifdef SQLITE_ENABLE_ASYNCIO |
| 21 | 28 |
| 22 #include "sqlite3async.h" | 29 #include "sqlite3async.h" |
| 23 #include "sqlite3.h" | 30 #include "sqlite3.h" |
| 24 #include <assert.h> | 31 #include <assert.h> |
| 25 | 32 |
| 26 /* From main.c */ | 33 /* From main.c */ |
| 27 extern const char *sqlite3ErrName(int); | 34 extern const char *sqlite3ErrName(int); |
| 28 | 35 |
| 29 | 36 |
| 30 struct TestAsyncGlobal { | 37 struct TestAsyncGlobal { |
| 31 int isInstalled; /* True when async VFS is installed */ | 38 int isInstalled; /* True when async VFS is installed */ |
| 32 } testasync_g = { 0 }; | 39 } testasync_g = { 0 }; |
| 33 | 40 |
| 34 TCL_DECLARE_MUTEX(testasync_g_writerMutex); | 41 TCL_DECLARE_MUTEX(testasync_g_writerMutex); |
| 35 | 42 |
| 36 /* | 43 /* |
| 37 ** sqlite3async_initialize PARENT-VFS ISDEFAULT | 44 ** sqlite3async_initialize PARENT-VFS ISDEFAULT |
| 38 */ | 45 */ |
| 39 static int testAsyncInit( | 46 static int SQLITE_TCLAPI testAsyncInit( |
| 40 void * clientData, | 47 void * clientData, |
| 41 Tcl_Interp *interp, | 48 Tcl_Interp *interp, |
| 42 int objc, | 49 int objc, |
| 43 Tcl_Obj *CONST objv[] | 50 Tcl_Obj *CONST objv[] |
| 44 ){ | 51 ){ |
| 45 const char *zParent; | 52 const char *zParent; |
| 46 int isDefault; | 53 int isDefault; |
| 47 int rc; | 54 int rc; |
| 48 | 55 |
| 49 if( objc!=3 ){ | 56 if( objc!=3 ){ |
| (...skipping 12 matching lines...) Expand all Loading... |
| 62 if( rc!=SQLITE_OK ){ | 69 if( rc!=SQLITE_OK ){ |
| 63 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); | 70 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); |
| 64 return TCL_ERROR; | 71 return TCL_ERROR; |
| 65 } | 72 } |
| 66 return TCL_OK; | 73 return TCL_OK; |
| 67 } | 74 } |
| 68 | 75 |
| 69 /* | 76 /* |
| 70 ** sqlite3async_shutdown | 77 ** sqlite3async_shutdown |
| 71 */ | 78 */ |
| 72 static int testAsyncShutdown( | 79 static int SQLITE_TCLAPI testAsyncShutdown( |
| 73 void * clientData, | 80 void * clientData, |
| 74 Tcl_Interp *interp, | 81 Tcl_Interp *interp, |
| 75 int objc, | 82 int objc, |
| 76 Tcl_Obj *CONST objv[] | 83 Tcl_Obj *CONST objv[] |
| 77 ){ | 84 ){ |
| 78 sqlite3async_shutdown(); | 85 sqlite3async_shutdown(); |
| 79 return TCL_OK; | 86 return TCL_OK; |
| 80 } | 87 } |
| 81 | 88 |
| 82 static Tcl_ThreadCreateType tclWriterThread(ClientData pIsStarted){ | 89 static Tcl_ThreadCreateType tclWriterThread(ClientData pIsStarted){ |
| 83 Tcl_MutexLock(&testasync_g_writerMutex); | 90 Tcl_MutexLock(&testasync_g_writerMutex); |
| 84 *((int *)pIsStarted) = 1; | 91 *((int *)pIsStarted) = 1; |
| 85 sqlite3async_run(); | 92 sqlite3async_run(); |
| 86 Tcl_MutexUnlock(&testasync_g_writerMutex); | 93 Tcl_MutexUnlock(&testasync_g_writerMutex); |
| 87 Tcl_ExitThread(0); | 94 Tcl_ExitThread(0); |
| 88 TCL_THREAD_CREATE_RETURN; | 95 TCL_THREAD_CREATE_RETURN; |
| 89 } | 96 } |
| 90 | 97 |
| 91 /* | 98 /* |
| 92 ** sqlite3async_start | 99 ** sqlite3async_start |
| 93 ** | 100 ** |
| 94 ** Start a new writer thread. | 101 ** Start a new writer thread. |
| 95 */ | 102 */ |
| 96 static int testAsyncStart( | 103 static int SQLITE_TCLAPI testAsyncStart( |
| 97 void * clientData, | 104 void * clientData, |
| 98 Tcl_Interp *interp, | 105 Tcl_Interp *interp, |
| 99 int objc, | 106 int objc, |
| 100 Tcl_Obj *CONST objv[] | 107 Tcl_Obj *CONST objv[] |
| 101 ){ | 108 ){ |
| 102 volatile int isStarted = 0; | 109 volatile int isStarted = 0; |
| 103 ClientData threadData = (ClientData)&isStarted; | 110 ClientData threadData = (ClientData)&isStarted; |
| 104 | 111 |
| 105 Tcl_ThreadId x; | 112 Tcl_ThreadId x; |
| 106 const int nStack = TCL_THREAD_STACK_DEFAULT; | 113 const int nStack = TCL_THREAD_STACK_DEFAULT; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 118 } | 125 } |
| 119 | 126 |
| 120 /* | 127 /* |
| 121 ** sqlite3async_wait | 128 ** sqlite3async_wait |
| 122 ** | 129 ** |
| 123 ** Wait for the current writer thread to terminate. | 130 ** Wait for the current writer thread to terminate. |
| 124 ** | 131 ** |
| 125 ** If the current writer thread is set to run forever then this | 132 ** If the current writer thread is set to run forever then this |
| 126 ** command would block forever. To prevent that, an error is returned. | 133 ** command would block forever. To prevent that, an error is returned. |
| 127 */ | 134 */ |
| 128 static int testAsyncWait( | 135 static int SQLITE_TCLAPI testAsyncWait( |
| 129 void * clientData, | 136 void * clientData, |
| 130 Tcl_Interp *interp, | 137 Tcl_Interp *interp, |
| 131 int objc, | 138 int objc, |
| 132 Tcl_Obj *CONST objv[] | 139 Tcl_Obj *CONST objv[] |
| 133 ){ | 140 ){ |
| 134 int eCond; | 141 int eCond; |
| 135 if( objc!=1 ){ | 142 if( objc!=1 ){ |
| 136 Tcl_WrongNumArgs(interp, 1, objv, ""); | 143 Tcl_WrongNumArgs(interp, 1, objv, ""); |
| 137 return TCL_ERROR; | 144 return TCL_ERROR; |
| 138 } | 145 } |
| 139 | 146 |
| 140 sqlite3async_control(SQLITEASYNC_GET_HALT, &eCond); | 147 sqlite3async_control(SQLITEASYNC_GET_HALT, &eCond); |
| 141 if( eCond==SQLITEASYNC_HALT_NEVER ){ | 148 if( eCond==SQLITEASYNC_HALT_NEVER ){ |
| 142 Tcl_AppendResult(interp, "would block forever", (char*)0); | 149 Tcl_AppendResult(interp, "would block forever", (char*)0); |
| 143 return TCL_ERROR; | 150 return TCL_ERROR; |
| 144 } | 151 } |
| 145 | 152 |
| 146 Tcl_MutexLock(&testasync_g_writerMutex); | 153 Tcl_MutexLock(&testasync_g_writerMutex); |
| 147 Tcl_MutexUnlock(&testasync_g_writerMutex); | 154 Tcl_MutexUnlock(&testasync_g_writerMutex); |
| 148 return TCL_OK; | 155 return TCL_OK; |
| 149 } | 156 } |
| 150 | 157 |
| 151 /* | 158 /* |
| 152 ** sqlite3async_control OPTION ?VALUE? | 159 ** sqlite3async_control OPTION ?VALUE? |
| 153 */ | 160 */ |
| 154 static int testAsyncControl( | 161 static int SQLITE_TCLAPI testAsyncControl( |
| 155 void * clientData, | 162 void * clientData, |
| 156 Tcl_Interp *interp, | 163 Tcl_Interp *interp, |
| 157 int objc, | 164 int objc, |
| 158 Tcl_Obj *CONST objv[] | 165 Tcl_Obj *CONST objv[] |
| 159 ){ | 166 ){ |
| 160 int rc = SQLITE_OK; | 167 int rc = SQLITE_OK; |
| 161 int aeOpt[] = { SQLITEASYNC_HALT, SQLITEASYNC_DELAY, SQLITEASYNC_LOCKFILES }; | 168 int aeOpt[] = { SQLITEASYNC_HALT, SQLITEASYNC_DELAY, SQLITEASYNC_LOCKFILES }; |
| 162 const char *azOpt[] = { "halt", "delay", "lockfiles", 0 }; | 169 const char *azOpt[] = { "halt", "delay", "lockfiles", 0 }; |
| 163 const char *az[] = { "never", "now", "idle", 0 }; | 170 const char *az[] = { "never", "now", "idle", 0 }; |
| 164 int iVal; | 171 int iVal; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 #ifdef SQLITE_ENABLE_ASYNCIO | 239 #ifdef SQLITE_ENABLE_ASYNCIO |
| 233 Tcl_CreateObjCommand(interp,"sqlite3async_start",testAsyncStart,0,0); | 240 Tcl_CreateObjCommand(interp,"sqlite3async_start",testAsyncStart,0,0); |
| 234 Tcl_CreateObjCommand(interp,"sqlite3async_wait",testAsyncWait,0,0); | 241 Tcl_CreateObjCommand(interp,"sqlite3async_wait",testAsyncWait,0,0); |
| 235 | 242 |
| 236 Tcl_CreateObjCommand(interp,"sqlite3async_control",testAsyncControl,0,0); | 243 Tcl_CreateObjCommand(interp,"sqlite3async_control",testAsyncControl,0,0); |
| 237 Tcl_CreateObjCommand(interp,"sqlite3async_initialize",testAsyncInit,0,0); | 244 Tcl_CreateObjCommand(interp,"sqlite3async_initialize",testAsyncInit,0,0); |
| 238 Tcl_CreateObjCommand(interp,"sqlite3async_shutdown",testAsyncShutdown,0,0); | 245 Tcl_CreateObjCommand(interp,"sqlite3async_shutdown",testAsyncShutdown,0,0); |
| 239 #endif /* SQLITE_ENABLE_ASYNCIO */ | 246 #endif /* SQLITE_ENABLE_ASYNCIO */ |
| 240 return TCL_OK; | 247 return TCL_OK; |
| 241 } | 248 } |
| OLD | NEW |