SQLite

Check-in [622c17177a]
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
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.000
Context
2010-01-30
23:08
The iInUseDB and iInUseMM variables do not need to be volatile. (Leaf check-in: bb18f57852 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: 622c17177a user: drh tags: branch-3.5.9)
19:17
Avoid a race condition in the sqlite3_release_memory() logic within pager.c. (check-in: a718e66347 user: drh tags: branch-3.5.9)
Changes
Unified Diff Ignore Whitespace 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
**
** 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){







>
|
|




<







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

529
530
531
532
533
534
535
**
** 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){
3314
3315
3316
3317
3318
3319
3320

3321
3322
3323

3324
3325
3326
3327
3328
3329
3330
    /* 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.
      **







>



>







3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
    /* 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.
      **