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
Side-by-Side 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
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++;
    if( p->iInUseMM && p->iInUseDB==1 ){
      p->iInUseDB++;
    }else{
#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){
3314
3315
3316
3317
3318
3319
3320

3321
3322
3323

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