Relinquish the pcache mutex before calling an xStress callback. This ensures that the pcache mutex is never held while IO is performed. (CVS 5599)
FossilOrigin-Name: 8fe234b2ca1292955162d38922a45c93004fb6ae
This commit is contained in:
parent
9d8b3072ce
commit
ed2781e3c8
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
|||||||
C Enhanced\stest\scoverage.\s(CVS\s5598)
|
C Relinquish\sthe\spcache\smutex\sbefore\scalling\san\sxStress\scallback.\sThis\sensures\sthat\sthe\spcache\smutex\sis\snever\sheld\swhile\sIO\sis\sperformed.\s(CVS\s5599)
|
||||||
D 2008-08-22T16:29:51
|
D 2008-08-22T17:09:50
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in 51b727303f84cf055e29514d8248e5eaf9701379
|
F Makefile.in 51b727303f84cf055e29514d8248e5eaf9701379
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@ -138,7 +138,7 @@ F src/os_win.c aefe9ee26430678a19a058a874e4e2bd91398142
|
|||||||
F src/pager.c 3b6625d32cd6f43c54c160f246545f9f26ba7668
|
F src/pager.c 3b6625d32cd6f43c54c160f246545f9f26ba7668
|
||||||
F src/pager.h 3778bea71dfb9658b6c94394e18db4a5b27e6ded
|
F src/pager.h 3778bea71dfb9658b6c94394e18db4a5b27e6ded
|
||||||
F src/parse.y d0f76d2cb8d6883d5600dc20beb961a6022b94b8
|
F src/parse.y d0f76d2cb8d6883d5600dc20beb961a6022b94b8
|
||||||
F src/pcache.c e12359db2963c379f18b52c657b5ec0ebb7a02cd
|
F src/pcache.c 504e6204124c4f90917ab1c0ea0a0ec549ed242f
|
||||||
F src/pcache.h 1457e4e7ef08f6964399d5c039afdece25071d54
|
F src/pcache.h 1457e4e7ef08f6964399d5c039afdece25071d54
|
||||||
F src/pragma.c f5b271b090af7fcedd308d7c5807a5503f7a853d
|
F src/pragma.c f5b271b090af7fcedd308d7c5807a5503f7a853d
|
||||||
F src/prepare.c c197041e0c4770672cda75e6bfe10242f885e510
|
F src/prepare.c c197041e0c4770672cda75e6bfe10242f885e510
|
||||||
@ -623,7 +623,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
|||||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||||
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
|
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
P 93dbc5427bebaa0b3d726731027caad3f70611c7
|
P cc36b4e016a1f519ca81d591de3a551ee8aa6813
|
||||||
R d06c1972a5218a66e3015476bedfa7df
|
R 64828ec133db995283a20c7be6e84925
|
||||||
U drh
|
U danielk1977
|
||||||
Z 9e8818091fbf71d795674002e4d9c171
|
Z 7437592fbd9eee9fb3293ff26d588a0d
|
||||||
|
@ -1 +1 @@
|
|||||||
cc36b4e016a1f519ca81d591de3a551ee8aa6813
|
8fe234b2ca1292955162d38922a45c93004fb6ae
|
50
src/pcache.c
50
src/pcache.c
@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file implements that page cache.
|
** This file implements that page cache.
|
||||||
**
|
**
|
||||||
** @(#) $Id: pcache.c,v 1.8 2008/08/22 16:22:17 danielk1977 Exp $
|
** @(#) $Id: pcache.c,v 1.9 2008/08/22 17:09:50 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -453,6 +453,14 @@ static int pcachePageSize(PgHdr *p){
|
|||||||
return sqlite3MallocSize(p);
|
return sqlite3MallocSize(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Recycle a page from the global LRU list. If no page can be recycled,
|
||||||
|
** return NULL. Otherwise, the pointer returned points to a PgHdr
|
||||||
|
** object that has been removed from all lists and hash tables in
|
||||||
|
** which is was referenced. The caller may reuse the allocation directly
|
||||||
|
** or may pass it to pcachePageFree() to return the memory to the heap
|
||||||
|
** (or pcache.pFree list).
|
||||||
|
*/
|
||||||
static PgHdr *pcacheRecycle(PCache *pCache){
|
static PgHdr *pcacheRecycle(PCache *pCache){
|
||||||
PgHdr *p = 0;
|
PgHdr *p = 0;
|
||||||
|
|
||||||
@ -465,31 +473,13 @@ static PgHdr *pcacheRecycle(PCache *pCache){
|
|||||||
}
|
}
|
||||||
if( p && (p->flags&PGHDR_DIRTY) ){
|
if( p && (p->flags&PGHDR_DIRTY) ){
|
||||||
if( SQLITE_OK==sqlite3_mutex_try(pcache.mutex_mem2) ){
|
if( SQLITE_OK==sqlite3_mutex_try(pcache.mutex_mem2) ){
|
||||||
int iInUseDB;
|
|
||||||
PCache *pC = p->pCache;
|
PCache *pC = p->pCache;
|
||||||
|
|
||||||
if( pCache==pC ){
|
|
||||||
/* If trying to recycle a page from pCache, then set the iInUseDb
|
|
||||||
** flag to zero. This is done so that the sqlite3PcacheSetFlags()
|
|
||||||
** can tell that the LRU mutex is already held.
|
|
||||||
**
|
|
||||||
** It is quite safe to modify the iInUseDB variable, because we
|
|
||||||
** know no other thread will attempt to use pCache (because this
|
|
||||||
** call is being made from within a call to sqlite3PcacheFetch()
|
|
||||||
** on pCache).
|
|
||||||
*/
|
|
||||||
assert( pCache->iInUseDB );
|
|
||||||
iInUseDB = pCache->iInUseDB;
|
|
||||||
pCache->iInUseDB = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert( pC->iInUseMM==0 );
|
assert( pC->iInUseMM==0 );
|
||||||
pC->iInUseMM = 1;
|
pC->iInUseMM = 1;
|
||||||
if( pC->xStress && pC->iInUseDB==0 ){
|
if( pC->xStress && (pC->iInUseDB==0 || pC==pCache) ){
|
||||||
|
pcacheExitGlobal();
|
||||||
pC->xStress(pC->pStress, p);
|
pC->xStress(pC->pStress, p);
|
||||||
}
|
pcacheEnterGlobal();
|
||||||
if( pCache==pC ){
|
|
||||||
pCache->iInUseDB = iInUseDB;
|
|
||||||
}
|
}
|
||||||
pC->iInUseMM = 0;
|
pC->iInUseMM = 0;
|
||||||
sqlite3_mutex_leave(pcache.mutex_mem2);
|
sqlite3_mutex_leave(pcache.mutex_mem2);
|
||||||
@ -766,7 +756,6 @@ void sqlite3PcacheMakeClean(PgHdr *p){
|
|||||||
if( (p->flags & PGHDR_DIRTY)==0 ) return;
|
if( (p->flags & PGHDR_DIRTY)==0 ) return;
|
||||||
assert( p->apSave[0]==0 && p->apSave[1]==0 );
|
assert( p->apSave[0]==0 && p->apSave[1]==0 );
|
||||||
assert( p->flags & PGHDR_DIRTY );
|
assert( p->flags & PGHDR_DIRTY );
|
||||||
assert( p->nRef>0 || sqlite3_mutex_held(pcache.mutex_lru) );
|
|
||||||
pCache = p->pCache;
|
pCache = p->pCache;
|
||||||
pcacheRemoveFromList(&pCache->pDirty, p);
|
pcacheRemoveFromList(&pCache->pDirty, p);
|
||||||
pcacheAddToList(&pCache->pClean, p);
|
pcacheAddToList(&pCache->pClean, p);
|
||||||
@ -1127,15 +1116,10 @@ void sqlite3PcacheSetFlags(PCache *pCache, int andMask, int orMask){
|
|||||||
assert( (orMask&PGHDR_NEED_SYNC)==0 );
|
assert( (orMask&PGHDR_NEED_SYNC)==0 );
|
||||||
assert( pCache->iInUseDB || pCache->iInUseMM );
|
assert( pCache->iInUseDB || pCache->iInUseMM );
|
||||||
|
|
||||||
/* If this call is being made from within a call to the xStress callback
|
/* Obtain the global mutex before modifying any PgHdr.flags variables
|
||||||
** of a pager-cache (i.e. from within pagerRecycle()), then the
|
** or traversing the LRU list.
|
||||||
** PCache.iInUseDB will be set to zero. In this case, the LRU mutex is
|
|
||||||
** already held. Otherwise, obtain it before modifying any PgHdr.flags
|
|
||||||
** variables or traversing the LRU list.
|
|
||||||
*/
|
*/
|
||||||
if( pCache->iInUseDB ){
|
pcacheEnterGlobal();
|
||||||
pcacheEnterGlobal();
|
|
||||||
}
|
|
||||||
assert( sqlite3_mutex_held(pcache.mutex_lru) );
|
assert( sqlite3_mutex_held(pcache.mutex_lru) );
|
||||||
|
|
||||||
for(p=pCache->pDirty; p; p=p->pNext){
|
for(p=pCache->pDirty; p; p=p->pNext){
|
||||||
@ -1150,9 +1134,7 @@ void sqlite3PcacheSetFlags(PCache *pCache, int andMask, int orMask){
|
|||||||
pcache.pLruSynced = p;
|
pcache.pLruSynced = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pCache->iInUseDB ){
|
pcacheExitGlobal();
|
||||||
pcacheExitGlobal();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user