aboutsummaryrefslogtreecommitdiff
path: root/src/test1.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/test1.c')
-rw-r--r--src/test1.c88
1 files changed, 74 insertions, 14 deletions
diff --git a/src/test1.c b/src/test1.c
index c204335dc..e45a05fe4 100644
--- a/src/test1.c
+++ b/src/test1.c
@@ -5947,6 +5947,42 @@ static int SQLITE_TCLAPI test_busy_timeout(
}
/*
+** Usage: sqlite3_setlk_timeout ?-blockonconnect? DB MS
+**
+** Set the setlk timeout.
+*/
+static int SQLITE_TCLAPI test_setlk_timeout(
+ void * clientData,
+ Tcl_Interp *interp,
+ int argc,
+ char **argv
+){
+ int rc, ms;
+ sqlite3 *db;
+ int bBlockOnConnect = 0;
+
+ if( argc==4 ){
+ const char *zArg = argv[1];
+ int nArg = strlen(zArg);
+ if( nArg>=2 && nArg<=15 && memcmp(zArg, "-blockonconnect", nArg)==0 ){
+ bBlockOnConnect = 1;
+ }
+ }
+ if( argc!=(3+bBlockOnConnect) ){
+ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+ " ?-blockonconnect? DB MS", 0);
+ return TCL_ERROR;
+ }
+ if( getDbPointer(interp, argv[argc-2], &db) ) return TCL_ERROR;
+ if( Tcl_GetInt(interp, argv[argc-1], &ms) ) return TCL_ERROR;
+ rc = sqlite3_setlk_timeout(
+ db, ms, (bBlockOnConnect ? SQLITE_SETLK_BLOCK_ON_CONNECT : 0)
+ );
+ Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
+ return TCL_OK;
+}
+
+/*
** Usage: tcl_variable_type VARIABLENAME
**
** Return the name of the internal representation for the
@@ -7939,7 +7975,7 @@ static int SQLITE_TCLAPI test_getrusage(
*/
struct win32FileLocker {
char *evName; /* Name of event to signal thread startup */
- HANDLE h; /* Handle of the file to be locked */
+ sqlite3_file *pFd; /* Handle of the file to be locked */
int delay1; /* Delay before locking */
int delay2; /* Delay before unlocking */
int ok; /* Finished ok */
@@ -7955,6 +7991,8 @@ struct win32FileLocker {
*/
static void SQLITE_CDECL win32_file_locker(void *pAppData){
struct win32FileLocker *p = (struct win32FileLocker*)pAppData;
+ sqlite3_file *pFd = p->pFd;
+ HANDLE h = INVALID_HANDLE_VALUE;
if( p->evName ){
HANDLE ev = OpenEvent(EVENT_MODIFY_STATE, FALSE, p->evName);
if ( ev ){
@@ -7963,15 +8001,17 @@ static void SQLITE_CDECL win32_file_locker(void *pAppData){
}
}
if( p->delay1 ) Sleep(p->delay1);
- if( LockFile(p->h, 0, 0, 100000000, 0) ){
+ pFd->pMethods->xFileControl(pFd, SQLITE_FCNTL_WIN32_GET_HANDLE, (void*)&h);
+ if( LockFile(h, 0, 0, 100000000, 0) ){
Sleep(p->delay2);
- UnlockFile(p->h, 0, 0, 100000000, 0);
+ UnlockFile(h, 0, 0, 100000000, 0);
p->ok = 1;
}else{
p->err = 1;
}
- CloseHandle(p->h);
- p->h = 0;
+ pFd->pMethods->xClose(pFd);
+ sqlite3_free(pFd);
+ p->pFd = 0;
p->delay1 = 0;
p->delay2 = 0;
}
@@ -7991,37 +8031,56 @@ static int SQLITE_TCLAPI win32_file_lock(
Tcl_Obj *CONST objv[]
){
static struct win32FileLocker x = { "win32_file_lock", 0, 0, 0, 0, 0 };
- const char *zFilename;
+ const char *zFilename = 0;
+ Tcl_Size nFilename = 0;
+ char *zTerm = 0;
char zBuf[200];
int retry = 0;
HANDLE ev;
DWORD wResult;
+ sqlite3_vfs *pVfs = 0;
+ int flags = SQLITE_OPEN_MAIN_DB | SQLITE_OPEN_READWRITE;
+ int rc = SQLITE_OK;
if( objc!=4 && objc!=1 ){
Tcl_WrongNumArgs(interp, 1, objv, "FILENAME DELAY1 DELAY2");
return TCL_ERROR;
}
if( objc==1 ){
+ HANDLE h = INVALID_HANDLE_VALUE;
+ if( x.pFd ){
+ x.pFd->pMethods->xFileControl(
+ x.pFd, SQLITE_FCNTL_WIN32_GET_HANDLE, (void*)&h
+ );
+ }
sqlite3_snprintf(sizeof(zBuf), zBuf, "%d %d %d %d %d",
- x.ok, x.err, x.delay1, x.delay2, x.h);
+ x.ok, x.err, x.delay1, x.delay2, h);
Tcl_AppendResult(interp, zBuf, (char*)0);
return TCL_OK;
}
- while( x.h && retry<30 ){
+ while( x.pFd && retry<30 ){
retry++;
Sleep(100);
}
- if( x.h ){
+ if( x.pFd ){
Tcl_AppendResult(interp, "busy", (char*)0);
return TCL_ERROR;
}
if( Tcl_GetIntFromObj(interp, objv[2], &x.delay1) ) return TCL_ERROR;
if( Tcl_GetIntFromObj(interp, objv[3], &x.delay2) ) return TCL_ERROR;
- zFilename = Tcl_GetString(objv[1]);
- x.h = CreateFile(zFilename, GENERIC_READ|GENERIC_WRITE,
- FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, 0);
- if( !x.h ){
+ pVfs = sqlite3_vfs_find(0);
+ x.pFd = (sqlite3_file*)sqlite3_malloc(pVfs->szOsFile);
+
+ /* xOpen() must be passed a dual-nul-terminated string preceded in memory
+ ** by 4 0x00 bytes. */
+ zFilename = Tcl_GetStringFromObj(objv[1], &nFilename);
+ zTerm = (char*)sqlite3_malloc(nFilename+6);
+ memset(zTerm, 0, nFilename+6);
+ memcpy(&zTerm[4], zFilename, nFilename);
+ rc = pVfs->xOpen(pVfs, &zTerm[4], x.pFd, flags, &flags);
+ sqlite3_free(zTerm);
+
+ if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, "cannot open file: ", zFilename, (char*)0);
return TCL_ERROR;
}
@@ -8848,6 +8907,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite_delete_collation", (Tcl_CmdProc*)delete_collation },
{ "sqlite3_get_autocommit", (Tcl_CmdProc*)get_autocommit },
{ "sqlite3_busy_timeout", (Tcl_CmdProc*)test_busy_timeout },
+ { "sqlite3_setlk_timeout", (Tcl_CmdProc*)test_setlk_timeout },
{ "printf", (Tcl_CmdProc*)test_printf },
{ "sqlite3IoTrace", (Tcl_CmdProc*)test_io_trace },
{ "clang_sanitize_address", (Tcl_CmdProc*)clang_sanitize_address },