Annotation of embedaddon/sqlite3/src/test_async.c, revision 1.1

1.1     ! misho       1: /*
        !             2: ** 2005 December 14
        !             3: **
        !             4: ** The author disclaims copyright to this source code.  In place of
        !             5: ** a legal notice, here is a blessing:
        !             6: **
        !             7: **    May you do good and not evil.
        !             8: **    May you find forgiveness for yourself and forgive others.
        !             9: **    May you share freely, never taking more than you give.
        !            10: **
        !            11: *************************************************************************
        !            12: **
        !            13: ** This file contains a binding of the asynchronous IO extension interface
        !            14: ** (defined in ext/async/sqlite3async.h) to Tcl.
        !            15: */
        !            16: 
        !            17: #define TCL_THREADS 
        !            18: #include <tcl.h>
        !            19: 
        !            20: #ifdef SQLITE_ENABLE_ASYNCIO
        !            21: 
        !            22: #include "sqlite3async.h"
        !            23: #include "sqlite3.h"
        !            24: #include <assert.h>
        !            25: 
        !            26: /* From test1.c */
        !            27: const char *sqlite3TestErrorName(int);
        !            28: 
        !            29: 
        !            30: struct TestAsyncGlobal {
        !            31:   int isInstalled;                     /* True when async VFS is installed */
        !            32: } testasync_g = { 0 };
        !            33: 
        !            34: TCL_DECLARE_MUTEX(testasync_g_writerMutex);
        !            35: 
        !            36: /*
        !            37: ** sqlite3async_initialize PARENT-VFS ISDEFAULT
        !            38: */
        !            39: static int testAsyncInit(
        !            40:   void * clientData,
        !            41:   Tcl_Interp *interp,
        !            42:   int objc,
        !            43:   Tcl_Obj *CONST objv[]
        !            44: ){
        !            45:   const char *zParent;
        !            46:   int isDefault;
        !            47:   int rc;
        !            48: 
        !            49:   if( objc!=3 ){
        !            50:     Tcl_WrongNumArgs(interp, 1, objv, "PARENT-VFS ISDEFAULT");
        !            51:     return TCL_ERROR;
        !            52:   }
        !            53:   zParent = Tcl_GetString(objv[1]);
        !            54:   if( !*zParent ) {
        !            55:     zParent = 0;
        !            56:   }
        !            57:   if( Tcl_GetBooleanFromObj(interp, objv[2], &isDefault) ){
        !            58:     return TCL_ERROR;
        !            59:   }
        !            60: 
        !            61:   rc = sqlite3async_initialize(zParent, isDefault);
        !            62:   if( rc!=SQLITE_OK ){
        !            63:     Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3TestErrorName(rc), -1));
        !            64:     return TCL_ERROR;
        !            65:   }
        !            66:   return TCL_OK;
        !            67: }
        !            68: 
        !            69: /*
        !            70: ** sqlite3async_shutdown
        !            71: */
        !            72: static int testAsyncShutdown(
        !            73:   void * clientData,
        !            74:   Tcl_Interp *interp,
        !            75:   int objc,
        !            76:   Tcl_Obj *CONST objv[]
        !            77: ){
        !            78:   sqlite3async_shutdown();
        !            79:   return TCL_OK;
        !            80: }
        !            81: 
        !            82: static Tcl_ThreadCreateType tclWriterThread(ClientData pIsStarted){
        !            83:   Tcl_MutexLock(&testasync_g_writerMutex);
        !            84:   *((int *)pIsStarted) = 1;
        !            85:   sqlite3async_run();
        !            86:   Tcl_MutexUnlock(&testasync_g_writerMutex);
        !            87:   Tcl_ExitThread(0);
        !            88:   TCL_THREAD_CREATE_RETURN;
        !            89: }
        !            90: 
        !            91: /*
        !            92: ** sqlite3async_start
        !            93: **
        !            94: ** Start a new writer thread.
        !            95: */
        !            96: static int testAsyncStart(
        !            97:   void * clientData,
        !            98:   Tcl_Interp *interp,
        !            99:   int objc,
        !           100:   Tcl_Obj *CONST objv[]
        !           101: ){
        !           102:   volatile int isStarted = 0;
        !           103:   ClientData threadData = (ClientData)&isStarted;
        !           104: 
        !           105:   Tcl_ThreadId x;
        !           106:   const int nStack = TCL_THREAD_STACK_DEFAULT;
        !           107:   const int flags = TCL_THREAD_NOFLAGS;
        !           108:   int rc;
        !           109: 
        !           110:   rc = Tcl_CreateThread(&x, tclWriterThread, threadData, nStack, flags);
        !           111:   if( rc!=TCL_OK ){
        !           112:     Tcl_AppendResult(interp, "Tcl_CreateThread() failed", 0);
        !           113:     return TCL_ERROR;
        !           114:   }
        !           115: 
        !           116:   while( isStarted==0 ) { /* Busy loop */ }
        !           117:   return TCL_OK;
        !           118: }
        !           119: 
        !           120: /*
        !           121: ** sqlite3async_wait
        !           122: **
        !           123: ** Wait for the current writer thread to terminate.
        !           124: **
        !           125: ** If the current writer thread is set to run forever then this
        !           126: ** command would block forever.  To prevent that, an error is returned. 
        !           127: */
        !           128: static int testAsyncWait(
        !           129:   void * clientData,
        !           130:   Tcl_Interp *interp,
        !           131:   int objc,
        !           132:   Tcl_Obj *CONST objv[]
        !           133: ){
        !           134:   int eCond;
        !           135:   if( objc!=1 ){
        !           136:     Tcl_WrongNumArgs(interp, 1, objv, "");
        !           137:     return TCL_ERROR;
        !           138:   }
        !           139: 
        !           140:   sqlite3async_control(SQLITEASYNC_GET_HALT, &eCond);
        !           141:   if( eCond==SQLITEASYNC_HALT_NEVER ){
        !           142:     Tcl_AppendResult(interp, "would block forever", (char*)0);
        !           143:     return TCL_ERROR;
        !           144:   }
        !           145: 
        !           146:   Tcl_MutexLock(&testasync_g_writerMutex);
        !           147:   Tcl_MutexUnlock(&testasync_g_writerMutex);
        !           148:   return TCL_OK;
        !           149: }
        !           150: 
        !           151: /*
        !           152: ** sqlite3async_control OPTION ?VALUE?
        !           153: */
        !           154: static int testAsyncControl(
        !           155:   void * clientData,
        !           156:   Tcl_Interp *interp,
        !           157:   int objc,
        !           158:   Tcl_Obj *CONST objv[]
        !           159: ){
        !           160:   int rc = SQLITE_OK;
        !           161:   int aeOpt[] = { SQLITEASYNC_HALT, SQLITEASYNC_DELAY, SQLITEASYNC_LOCKFILES };
        !           162:   const char *azOpt[] = { "halt", "delay", "lockfiles", 0 };
        !           163:   const char *az[] = { "never", "now", "idle", 0 };
        !           164:   int iVal;
        !           165:   int eOpt;
        !           166: 
        !           167:   if( objc!=2 && objc!=3 ){
        !           168:     Tcl_WrongNumArgs(interp, 1, objv, "OPTION ?VALUE?");
        !           169:     return TCL_ERROR;
        !           170:   }
        !           171:   if( Tcl_GetIndexFromObj(interp, objv[1], azOpt, "option", 0, &eOpt) ){
        !           172:     return TCL_ERROR;
        !           173:   }
        !           174:   eOpt = aeOpt[eOpt];
        !           175: 
        !           176:   if( objc==3 ){
        !           177:     switch( eOpt ){
        !           178:       case SQLITEASYNC_HALT: {
        !           179:         assert( SQLITEASYNC_HALT_NEVER==0 );
        !           180:         assert( SQLITEASYNC_HALT_NOW==1 );
        !           181:         assert( SQLITEASYNC_HALT_IDLE==2 );
        !           182:         if( Tcl_GetIndexFromObj(interp, objv[2], az, "value", 0, &iVal) ){
        !           183:           return TCL_ERROR;
        !           184:         }
        !           185:         break;
        !           186:       }
        !           187:       case SQLITEASYNC_DELAY:
        !           188:         if( Tcl_GetIntFromObj(interp, objv[2], &iVal) ){
        !           189:           return TCL_ERROR;
        !           190:         }
        !           191:         break;
        !           192: 
        !           193:       case SQLITEASYNC_LOCKFILES:
        !           194:         if( Tcl_GetBooleanFromObj(interp, objv[2], &iVal) ){
        !           195:           return TCL_ERROR;
        !           196:         }
        !           197:         break;
        !           198:     }
        !           199: 
        !           200:     rc = sqlite3async_control(eOpt, iVal);
        !           201:   }
        !           202: 
        !           203:   if( rc==SQLITE_OK ){
        !           204:     rc = sqlite3async_control(
        !           205:         eOpt==SQLITEASYNC_HALT ? SQLITEASYNC_GET_HALT :
        !           206:         eOpt==SQLITEASYNC_DELAY ? SQLITEASYNC_GET_DELAY :
        !           207:         SQLITEASYNC_GET_LOCKFILES, &iVal);
        !           208:   }
        !           209: 
        !           210:   if( rc!=SQLITE_OK ){
        !           211:     Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3TestErrorName(rc), -1));
        !           212:     return TCL_ERROR;
        !           213:   }
        !           214: 
        !           215:   if( eOpt==SQLITEASYNC_HALT ){
        !           216:     Tcl_SetObjResult(interp, Tcl_NewStringObj(az[iVal], -1));
        !           217:   }else{
        !           218:     Tcl_SetObjResult(interp, Tcl_NewIntObj(iVal));
        !           219:   }
        !           220: 
        !           221:   return TCL_OK;
        !           222: }
        !           223: 
        !           224: #endif  /* SQLITE_ENABLE_ASYNCIO */
        !           225: 
        !           226: /*
        !           227: ** This routine registers the custom TCL commands defined in this
        !           228: ** module.  This should be the only procedure visible from outside
        !           229: ** of this module.
        !           230: */
        !           231: int Sqlitetestasync_Init(Tcl_Interp *interp){
        !           232: #ifdef SQLITE_ENABLE_ASYNCIO
        !           233:   Tcl_CreateObjCommand(interp,"sqlite3async_start",testAsyncStart,0,0);
        !           234:   Tcl_CreateObjCommand(interp,"sqlite3async_wait",testAsyncWait,0,0);
        !           235: 
        !           236:   Tcl_CreateObjCommand(interp,"sqlite3async_control",testAsyncControl,0,0);
        !           237:   Tcl_CreateObjCommand(interp,"sqlite3async_initialize",testAsyncInit,0,0);
        !           238:   Tcl_CreateObjCommand(interp,"sqlite3async_shutdown",testAsyncShutdown,0,0);
        !           239: #endif  /* SQLITE_ENABLE_ASYNCIO */
        !           240:   return TCL_OK;
        !           241: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>