diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/btree.c | 12 | ||||
-rw-r--r-- | src/os_win.c | 14 | ||||
-rw-r--r-- | src/test6.c | 4 | ||||
-rw-r--r-- | src/test7.c | 18 | ||||
-rw-r--r-- | src/test_server.c | 26 |
5 files changed, 65 insertions, 9 deletions
diff --git a/src/btree.c b/src/btree.c index 3ce70fe48..d56dfbddb 100644 --- a/src/btree.c +++ b/src/btree.c @@ -2052,6 +2052,18 @@ static int removeFromSharingList(BtShared *pBt){ static void allocateTempSpace(BtShared *pBt){ if( !pBt->pTmpSpace ){ pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize ); + + /* One of the uses of pBt->pTmpSpace is to format cells before + ** inserting them into a leaf page (function fillInCell()). If + ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes + ** by the various routines that manipulate binary cells. Which + ** can mean that fillInCell() only initializes the first 2 or 3 + ** bytes of pTmpSpace, but that the first 4 bytes are copied from + ** it into a database page. This is not actually a problem, but it + ** does cause a valgrind error when the 1 or 2 bytes of unitialized + ** data is passed to system call write(). So to avoid this error, + ** zero the first 4 bytes of temp space here. */ + if( pBt->pTmpSpace ) memset(pBt->pTmpSpace, 0, 4); } } diff --git a/src/os_win.c b/src/os_win.c index e1ed22c33..c6c567c00 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -2196,8 +2196,7 @@ static int winClose(sqlite3_file *id){ OSTRACE(("CLOSE file=%p\n", pFile->h)); #if SQLITE_MAX_MMAP_SIZE>0 - rc = winUnmapfile(pFile); - if( rc!=SQLITE_OK ) return rc; + winUnmapfile(pFile); #endif do{ @@ -3003,7 +3002,7 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){ pFile->mmapSizeMax = newLimit; if( pFile->mmapSize>0 ){ - (void)winUnmapfile(pFile); + winUnmapfile(pFile); rc = winMapfile(pFile, -1); } } @@ -3220,7 +3219,7 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ while( (p = *pp)!=0 ){ if( p->nRef==0 ){ int i; - if( p->mutex ) sqlite3_mutex_free(p->mutex); + if( p->mutex ){ sqlite3_mutex_free(p->mutex); } for(i=0; i<p->nRegion; i++){ BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap); OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n", @@ -4073,6 +4072,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ if( winIsDriveLetterAndColon(zDir) ){ zConverted = winConvertFromUtf8Filename(zDir); if( !zConverted ){ + sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); return SQLITE_IOERR_NOMEM; } @@ -4085,6 +4085,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ }else{ zConverted = sqlite3MallocZero( nBuf+1 ); if( !zConverted ){ + sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); return SQLITE_IOERR_NOMEM; } @@ -4092,6 +4093,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir, zConverted, nBuf+1)<0 ){ sqlite3_free(zConverted); + sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n")); return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno, "winGetTempname1", zDir); @@ -4105,6 +4107,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ char *zUtf8 = winUnicodeToUtf8(zConverted); if( !zUtf8 ){ sqlite3_free(zConverted); + sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); return SQLITE_IOERR_NOMEM; } @@ -4120,7 +4123,6 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ } sqlite3_free(zConverted); } - break; } } #elif !SQLITE_OS_WINRT && !defined(__CYGWIN__) @@ -4490,9 +4492,9 @@ static int winOpen( #endif { sqlite3_free(zConverted); - sqlite3_free(zTmpname); } + sqlite3_free(zTmpname); pFile->pMethod = &winIoMethod; pFile->pVfs = pVfs; pFile->h = h; diff --git a/src/test6.c b/src/test6.c index c151ea429..2020885c4 100644 --- a/src/test6.c +++ b/src/test6.c @@ -133,9 +133,9 @@ struct CrashFile { ** OsFileSize() calls. Although both could be done by traversing the ** write-list, in practice this is impractically slow. */ - int iSize; /* Size of file in bytes */ - int nData; /* Size of buffer allocated at zData */ u8 *zData; /* Buffer containing file contents */ + int nData; /* Size of buffer allocated at zData */ + i64 iSize; /* Size of file in bytes */ }; struct CrashGlobal { diff --git a/src/test7.c b/src/test7.c index 3cd4a224d..93bf1e489 100644 --- a/src/test7.c +++ b/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; } diff --git a/src/test_server.c b/src/test_server.c index ed0818e6f..4eb1cf196 100644 --- a/src/test_server.c +++ b/src/test_server.c @@ -473,6 +473,32 @@ void sqlite3_server_start(void){ } /* +** A wrapper around sqlite3_server() that decrements the int variable +** pointed to by the first argument after the sqlite3_server() call +** returns. +*/ +static void *serverWrapper(void *pnDecr){ + void *p = sqlite3_server(0); + (*(int*)pnDecr)--; + return p; +} + +/* +** This function is the similar to sqlite3_server_start(), except that +** the integer pointed to by the first argument is decremented when +** the server thread exits. +*/ +void sqlite3_server_start2(int *pnDecr){ + pthread_t x; + int rc; + g.serverHalt = 0; + rc = pthread_create(&x, 0, serverWrapper, (void*)pnDecr); + if( rc==0 ){ + pthread_detach(x); + } +} + +/* ** If a server thread is running, then stop it. If no server is ** running, this routine is effectively a no-op. ** |