1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

Hold the database mutex for the duration of an sqlite3changeset_apply() call. Also for the duration of all sqlite3session_xxx() calls.

FossilOrigin-Name: c615c38c3283e21c33550c093099a793761123a7
This commit is contained in:
dan
2011-03-18 18:03:13 +00:00
parent 304637c026
commit 4c22025225
6 changed files with 45 additions and 37 deletions

View File

@ -752,7 +752,9 @@ static void xPreUpdate(
sqlite3_session *pSession;
int nDb = strlen(zDb);
int nName = strlen(zDb);
assert( sqlite3_mutex_held(db->mutex) );
for(pSession=(sqlite3_session *)pCtx; pSession; pSession=pSession->pNext){
SessionTable *pTab;
@ -866,28 +868,34 @@ int sqlite3session_attach(
){
SessionTable *pTab; /* New table object (if required) */
int nName; /* Number of bytes in string zName */
int rc = SQLITE_OK;
sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
/* First search for an existing entry. If one is found, this call is
** a no-op. Return early. */
nName = strlen(zName);
for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){
if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ){
return SQLITE_OK;
if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ) break;
}
if( !pTab ){
/* Allocate new SessionTable object. */
pTab = (SessionTable *)sqlite3_malloc(sizeof(SessionTable) + nName + 1);
if( !pTab ){
rc = SQLITE_NOMEM;
}else{
/* Populate the new SessionTable object and link it into the list. */
memset(pTab, 0, sizeof(SessionTable));
pTab->zName = (char *)&pTab[1];
memcpy(pTab->zName, zName, nName+1);
pTab->pNext = pSession->pTable;
pSession->pTable = pTab;
}
}
/* Allocate new SessionTable object. */
pTab = (SessionTable *)sqlite3_malloc(sizeof(SessionTable) + nName + 1);
if( !pTab ) return SQLITE_NOMEM;
/* Populate the new SessionTable object and link it into the list. */
memset(pTab, 0, sizeof(SessionTable));
pTab->zName = (char *)&pTab[1];
memcpy(pTab->zName, zName, nName+1);
pTab->pNext = pSession->pTable;
pSession->pTable = pTab;
return SQLITE_OK;
sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
return rc;
}
/*
@ -1285,6 +1293,8 @@ int sqlite3session_changeset(
SessionBuffer buf = {0,0,0}; /* Buffer in which to accumlate changeset */
int rc; /* Return code */
sqlite3_mutex_enter(sqlite3_db_mutex(db));
/* Zero the output variables in case an error occurs. If this session
** object is already in the error state (sqlite3_session.rc != SQLITE_OK),
** this call will be a no-op. */
@ -1357,6 +1367,8 @@ int sqlite3session_changeset(
}else{
sqlite3_free(buf.aBuf);
}
sqlite3_mutex_leave(sqlite3_db_mutex(db));
return rc;
}
@ -1364,10 +1376,14 @@ int sqlite3session_changeset(
** Enable or disable the session object passed as the first argument.
*/
int sqlite3session_enable(sqlite3_session *pSession, int bEnable){
int ret;
sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
if( bEnable>=0 ){
pSession->bEnable = bEnable;
}
return pSession->bEnable;
ret = pSession->bEnable;
sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
return ret;
}
/*
@ -2277,6 +2293,7 @@ int sqlite3changeset_apply(
memset(&sApply, 0, sizeof(sApply));
sqlite3changeset_start(&pIter, nChangeset, pChangeset);
sqlite3_mutex_enter(sqlite3_db_mutex(db));
rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0);
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter) ){
int nCol;
@ -2366,6 +2383,7 @@ int sqlite3changeset_apply(
sqlite3_finalize(sApply.pUpdate);
sqlite3_finalize(sApply.pSelect);
sqlite3_free(sApply.azCol);
sqlite3_mutex_leave(sqlite3_db_mutex(db));
return rc;
}