/ 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 Unified Diffs Show Whitespace Changes Patch

Changes to src/pager.c.

515
516
517
518
519
520
521
522
523

524
525
526
527
528
529
530
531
532
533
534
535
....
3314
3315
3316
3317
3318
3319
3320

3321
3322
3323

3324
3325
3326
3327
3328
3329
3330
**
** The pagerMutexHeld(X) macro is for sanity checking.  This macro verifies
** that the database-connection mutex is held for pager X and asserts if it
** is not.
*/
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  static void pagerEnter(Pager *p){
    p->iInUseDB++;
    if( p->iInUseMM && p->iInUseDB==1 ){

#ifndef SQLITE_MUTEX_NOOP
      sqlite3_mutex *mutex;
      mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2);
#endif
      p->iInUseDB = 0;
      sqlite3_mutex_enter(mutex);
      assert( p->iInUseMM==0 );
      p->iInUseDB = 1;
      sqlite3_mutex_leave(mutex);
    }
  }
  static void pagerLeave(Pager *p){
................................................................................
    /* If pPg==0, then the block above has failed to find a page to
    ** recycle. In this case return early - no further memory will
    ** be released.
    */
    if( !pPg ) break;

    pPager = pPg->pPager;

    savedBusy = pPager->pBusyHandler;
    pPager->pBusyHandler = 0;
    rc = pager_recycle(pPager, &pPg);

    pPager->pBusyHandler = savedBusy;
    if( rc==SQLITE_OK ){
      /* We've found a page to free. At this point the page has been 
      ** removed from the page hash-table, free-list and synced-list 
      ** (pFirstSynced). It is still in the all pages (pAll) list. 
      ** Remove it from this list before freeing.
      **







|
|
>




<







 







>



>







515
516
517
518
519
520
521
522
523
524
525
526
527
528

529
530
531
532
533
534
535
....
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
**
** The pagerMutexHeld(X) macro is for sanity checking.  This macro verifies
** that the database-connection mutex is held for pager X and asserts if it
** is not.
*/
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  static void pagerEnter(Pager *p){
    if( p->iInUseDB>0 ){
      p->iInUseDB++;
    }else{
#ifndef SQLITE_MUTEX_NOOP
      sqlite3_mutex *mutex;
      mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2);
#endif

      sqlite3_mutex_enter(mutex);
      assert( p->iInUseMM==0 );
      p->iInUseDB = 1;
      sqlite3_mutex_leave(mutex);
    }
  }
  static void pagerLeave(Pager *p){
................................................................................
    /* If pPg==0, then the block above has failed to find a page to
    ** recycle. In this case return early - no further memory will
    ** be released.
    */
    if( !pPg ) break;

    pPager = pPg->pPager;
    assert( pPager->iInUseDB==0 );
    savedBusy = pPager->pBusyHandler;
    pPager->pBusyHandler = 0;
    rc = pager_recycle(pPager, &pPg);
    assert( pPager->iInUseDB==0 );
    pPager->pBusyHandler = savedBusy;
    if( rc==SQLITE_OK ){
      /* We've found a page to free. At this point the page has been 
      ** removed from the page hash-table, free-list and synced-list 
      ** (pFirstSynced). It is still in the all pages (pAll) list. 
      ** Remove it from this list before freeing.
      **