From 4c22025225fdef09f13b27fd5d364cd612136066 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 18 Mar 2011 18:03:13 +0000 Subject: [PATCH] Hold the database mutex for the duration of an sqlite3changeset_apply() call. Also for the duration of all sqlite3session_xxx() calls. FossilOrigin-Name: c615c38c3283e21c33550c093099a793761123a7 --- ext/session/sqlite3session.c | 50 ++++++++++++++++++++++++------------ install-sh | 0 manifest | 30 ++++++++-------------- manifest.uuid | 2 +- test/progress.test | 0 tool/mkopts.tcl | 0 6 files changed, 45 insertions(+), 37 deletions(-) mode change 100755 => 100644 install-sh mode change 100644 => 100755 test/progress.test mode change 100644 => 100755 tool/mkopts.tcl diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 296875052e..64114718de 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -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; } diff --git a/install-sh b/install-sh old mode 100755 new mode 100644 diff --git a/manifest b/manifest index ad7e4b5e21..0bcad83403 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Fixes\sfor\scompiler\swarnings.\s\sMinor\scode\scleanup. -D 2011-03-18T16:47:27.202 +C Hold\sthe\sdatabase\smutex\sfor\sthe\sduration\sof\san\ssqlite3changeset_apply()\scall.\sAlso\sfor\sthe\sduration\sof\sall\ssqlite3session_xxx()\scalls. +D 2011-03-18T18:03:14 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -102,10 +99,10 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F ext/session/sqlite3session.c 4183792547af5b5d3ec1c8a3f858beb172682503 +F ext/session/sqlite3session.c d4ba709d457a7b184a72ccd3ab07e5a1e9dd9196 F ext/session/sqlite3session.h 9551c002efd5fde07c52994c6b592308e0df2d6a F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 -F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x +F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F main.mk ae0868e05c76eaa8a0ae3d6927a949b1c8e810d7 F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a @@ -608,7 +605,7 @@ F test/permutations.test 5b2a4cb756ffb2407cb4743163668d1d769febb6 F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47 F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea -F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 +F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quota.test ddafe133653093eb9a99ccd6264884ae43f9c9b8 @@ -896,7 +893,7 @@ F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/lemon.c dfd81a51b6e27e469ba21d01a75ddf092d429027 F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/mkkeywordhash.c d2e6b4a5965e23afb80fbe74bb54648cd371f309 -F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e +F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c.tcl cf44512a48112b1ba09590548660a5a6877afdb3 F tool/mksqlite3h.tcl d76c226a5e8e1f3b5f6593bcabe5e98b3b1ec9ff @@ -921,14 +918,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 07019bb9e8d8f2445d1e0342f74ab520e9804cb5 -R e362c18925cab750a71fcf91528dddfb -U drh -Z 33df56341351167813c56b1a83010bf4 ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFNg4yioxKgR168RlERAsv6AJ9WZ1HLGm+YuNBznpVVZgVxxs49RwCdFrGC -OY796dAcZJ0MQ5I3+TprmmI= -=87W+ ------END PGP SIGNATURE----- +P 9604d13001e0a195718c7f03fc0e73e352226caa +R 54e501f64ecb85ba88c3d3201e5dcd9b +U dan +Z 255e99dc78fad5aee707e21b8ff77ea9 diff --git a/manifest.uuid b/manifest.uuid index fe2f62ed4f..235b1b6cb5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9604d13001e0a195718c7f03fc0e73e352226caa \ No newline at end of file +c615c38c3283e21c33550c093099a793761123a7 \ No newline at end of file diff --git a/test/progress.test b/test/progress.test old mode 100644 new mode 100755 diff --git a/tool/mkopts.tcl b/tool/mkopts.tcl old mode 100644 new mode 100755