aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/btree.c12
-rw-r--r--src/os_win.c14
-rw-r--r--src/test6.c4
-rw-r--r--src/test7.c18
-rw-r--r--src/test_server.c26
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.
**