/ Check-in [622c1717]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Always hold the MEM2 mutex when initially marking a pager as in use by its database connection.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | branch-3.5.9
Files: files | file ages | folders
SHA1: 622c17177af6851fec11bdec8fb6246c13135b2f
User & Date: drh 2010-01-30 22:28:47
Context
2010-01-30
23:08
The iInUseDB and iInUseMM variables do not need to be volatile. Leaf check-in: bb18f578 user: drh tags: branch-3.5.9
22:28
Always hold the MEM2 mutex when initially marking a pager as in use by its database connection. check-in: 622c1717 user: drh tags: branch-3.5.9
19:17
Avoid a race condition in the sqlite3_release_memory() logic within pager.c. check-in: a718e663 user: drh tags: branch-3.5.9
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/pager.c.

   515    515   **
   516    516   ** The pagerMutexHeld(X) macro is for sanity checking.  This macro verifies
   517    517   ** that the database-connection mutex is held for pager X and asserts if it
   518    518   ** is not.
   519    519   */
   520    520   #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
   521    521     static void pagerEnter(Pager *p){
   522         -    p->iInUseDB++;
   523         -    if( p->iInUseMM && p->iInUseDB==1 ){
          522  +    if( p->iInUseDB>0 ){
          523  +      p->iInUseDB++;
          524  +    }else{
   524    525   #ifndef SQLITE_MUTEX_NOOP
   525    526         sqlite3_mutex *mutex;
   526    527         mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2);
   527    528   #endif
   528         -      p->iInUseDB = 0;
   529    529         sqlite3_mutex_enter(mutex);
   530    530         assert( p->iInUseMM==0 );
   531    531         p->iInUseDB = 1;
   532    532         sqlite3_mutex_leave(mutex);
   533    533       }
   534    534     }
   535    535     static void pagerLeave(Pager *p){
................................................................................
  3314   3314       /* If pPg==0, then the block above has failed to find a page to
  3315   3315       ** recycle. In this case return early - no further memory will
  3316   3316       ** be released.
  3317   3317       */
  3318   3318       if( !pPg ) break;
  3319   3319   
  3320   3320       pPager = pPg->pPager;
         3321  +    assert( pPager->iInUseDB==0 );
  3321   3322       savedBusy = pPager->pBusyHandler;
  3322   3323       pPager->pBusyHandler = 0;
  3323   3324       rc = pager_recycle(pPager, &pPg);
         3325  +    assert( pPager->iInUseDB==0 );
  3324   3326       pPager->pBusyHandler = savedBusy;
  3325   3327       if( rc==SQLITE_OK ){
  3326   3328         /* We've found a page to free. At this point the page has been 
  3327   3329         ** removed from the page hash-table, free-list and synced-list 
  3328   3330         ** (pFirstSynced). It is still in the all pages (pAll) list. 
  3329   3331         ** Remove it from this list before freeing.
  3330   3332         **