SQLite

Check-in [9622dd468c]
Login

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

Overview
Comment:Do not hold the shared-memory mutex in os_unix.c if returning NULL.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | wal-incr-ckpt
Files: files | file ages | folders
SHA1: 9622dd468c8914262e9d8bd8dbca9e22ec6ee75c
User & Date: dan 2010-06-01 11:08:57.000
Context
2010-06-01
12:58
Fix an off-by-one boundary-value issue in walCleanupHash(). (check-in: f039552e63 user: drh tags: wal-incr-ckpt)
11:08
Do not hold the shared-memory mutex in os_unix.c if returning NULL. (check-in: 9622dd468c user: dan tags: wal-incr-ckpt)
10:44
If the checkpoint fails to obtain an exclusive lock on one of the read-lock bytes, do not consider this an error. (check-in: 9e95e35728 user: dan tags: wal-incr-ckpt)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/os_unix.c.
3402
3403
3404
3405
3406
3407
3408

3409
3410
3411
3412
3413
3414
3415
  /* Remove connection p from the set of connections associated
  ** with pShmNode */
  sqlite3_mutex_enter(pShmNode->mutex);
  for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
  *pp = p->pNext;

  /* Free the connection p */

  sqlite3_free(p);
  pDbFd->pShm = 0;
  sqlite3_mutex_leave(pShmNode->mutex);

  /* If pShmNode->nRef has reached 0, then close the underlying
  ** shared-memory file, too */
  unixEnterMutex();







>







3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
  /* Remove connection p from the set of connections associated
  ** with pShmNode */
  sqlite3_mutex_enter(pShmNode->mutex);
  for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
  *pp = p->pNext;

  /* Free the connection p */
  assert( p->hasMutexBuf==0 );
  sqlite3_free(p);
  pDbFd->pShm = 0;
  sqlite3_mutex_leave(pShmNode->mutex);

  /* If pShmNode->nRef has reached 0, then close the underlying
  ** shared-memory file, too */
  unixEnterMutex();
3460
3461
3462
3463
3464
3465
3466





















3467
3468
3469
3470
3471
3472
3473
    }
    rc = ftruncate(pShmNode->h, reqSize);
    reqSize = -1;
  }
  return rc;
}























/*
** Map the shared storage into memory. 
**
** If reqMapSize is positive, then an attempt is made to make the
** mapping at least reqMapSize bytes in size.  However, the mapping
** will never be larger than the size of the underlying shared memory







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
    }
    rc = ftruncate(pShmNode->h, reqSize);
    reqSize = -1;
  }
  return rc;
}

/*
** Release the lock held on the shared memory segment to that other
** threads are free to resize it if necessary.
**
** If the lock is not currently held, this routine is a harmless no-op.
**
** If the shared-memory object is in lock state RECOVER, then we do not
** really want to release the lock, so in that case too, this routine
** is a no-op.
*/
static int unixShmRelease(sqlite3_file *fd){
  unixFile *pDbFd = (unixFile*)fd;
  unixShm *p = pDbFd->pShm;

  if( p->hasMutexBuf ){
    assert( sqlite3_mutex_notheld(p->pShmNode->mutex) );
    sqlite3_mutex_leave(p->pShmNode->mutexBuf);
    p->hasMutexBuf = 0;
  }
  return SQLITE_OK;
}

/*
** Map the shared storage into memory. 
**
** If reqMapSize is positive, then an attempt is made to make the
** mapping at least reqMapSize bytes in size.  However, the mapping
** will never be larger than the size of the underlying shared memory
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
      pShmNode->pMMapBuf = 0;
      pShmNode->szMap = 0;
    }
  }
  *pNewMapSize = pShmNode->szMap;
  *ppBuf = pShmNode->pMMapBuf;
  sqlite3_mutex_leave(pShmNode->mutex);
  return rc;
}

/*
** Release the lock held on the shared memory segment to that other
** threads are free to resize it if necessary.
**
** If the lock is not currently held, this routine is a harmless no-op.
**
** If the shared-memory object is in lock state RECOVER, then we do not
** really want to release the lock, so in that case too, this routine
** is a no-op.
*/
static int unixShmRelease(sqlite3_file *fd){
  unixFile *pDbFd = (unixFile*)fd;
  unixShm *p = pDbFd->pShm;

  if( p->hasMutexBuf ){
    assert( sqlite3_mutex_notheld(p->pShmNode->mutex) );
    sqlite3_mutex_leave(p->pShmNode->mutexBuf);
    p->hasMutexBuf = 0;
  }
  return SQLITE_OK;
}


/*
** Change the lock state for a shared-memory segment.
**
** Note that the relationship between SHAREd and EXCLUSIVE locks is a little
** different here than in posix.  In xShmLock(), one can go from unlocked
** to shared and back or from unlocked to exclusive and back.  But one may







|
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
|









3555
3556
3557
3558
3559
3560
3561
3562

3563










3564


3565





3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
      pShmNode->pMMapBuf = 0;
      pShmNode->szMap = 0;
    }
  }
  *pNewMapSize = pShmNode->szMap;
  *ppBuf = pShmNode->pMMapBuf;
  sqlite3_mutex_leave(pShmNode->mutex);
  if( *ppBuf==0 ){

    /* Do not hold the mutex if a NULL pointer is being returned. */










    unixShmRelease(fd);


  }





  return rc;
}


/*
** Change the lock state for a shared-memory segment.
**
** Note that the relationship between SHAREd and EXCLUSIVE locks is a little
** different here than in posix.  In xShmLock(), one can go from unlocked
** to shared and back or from unlocked to exclusive and back.  But one may