/ Check-in [971a9650]
Login

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

Overview
Comment:If an OOM error occurs just after obtaining a shared lock on the database file, release the lock before returning. (CVS 6795)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:971a9650f66f079630489c34e40003eee97d1683
User & Date: danielk1977 2009-06-22 05:43:24
Context
2009-06-22
11:10
More simplifications to vdbe.c. Remove a NEVER() from vdbe.c that is possible after all. (CVS 6796) check-in: c8f009bd user: drh tags: trunk
05:43
If an OOM error occurs just after obtaining a shared lock on the database file, release the lock before returning. (CVS 6795) check-in: 971a9650 user: danielk1977 tags: trunk
00:55
Simplifications to vdbe.c in support of coverage testing. (CVS 6794) check-in: 16680f05 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/pager.c.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
....
3865
3866
3867
3868
3869
3870
3871

3872
3873
3874
3875
3876
3877
3878
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.600 2009/06/20 18:52:50 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"

/*
** Macros for troubleshooting.  Normally turned off
*/
................................................................................
  if( rc!=SQLITE_OK ){
    return rc;
  }
  assert( pPager->state!=PAGER_UNLOCK );

  rc = sqlite3PcacheFetch(pPager->pPCache, pgno, 1, &pPg);
  if( rc!=SQLITE_OK ){

    return rc;
  }
  assert( pPg->pgno==pgno );
  assert( pPg->pPager==pPager || pPg->pPager==0 );
  if( pPg->pPager==0 ){
    /* The pager cache has created a new page. Its content needs to 
    ** be initialized.







|







 







>







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
....
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.601 2009/06/22 05:43:24 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"

/*
** Macros for troubleshooting.  Normally turned off
*/
................................................................................
  if( rc!=SQLITE_OK ){
    return rc;
  }
  assert( pPager->state!=PAGER_UNLOCK );

  rc = sqlite3PcacheFetch(pPager->pPCache, pgno, 1, &pPg);
  if( rc!=SQLITE_OK ){
    pagerUnlockIfUnused(pPager);
    return rc;
  }
  assert( pPg->pgno==pgno );
  assert( pPg->pPager==pPager || pPg->pPager==0 );
  if( pPg->pPager==0 ){
    /* The pager cache has created a new page. Its content needs to 
    ** be initialized.

Changes to test/malloc.test.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
836
837
838
839
840
841
842























843
844
845
846
847
848
849
850
851
# This file attempts to check the behavior of the SQLite library in 
# an out-of-memory situation. When compiled with -DSQLITE_DEBUG=1, 
# the SQLite library accepts a special command (sqlite3_memdebug_fail N C)
# which causes the N-th malloc to fail.  This special feature is used
# to see what happens in the library if a malloc were to really fail
# due to an out-of-memory situation.
#
# $Id: malloc.test,v 1.79 2009/06/06 16:08:23 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl


# Only run these tests if memory debugging is turned on.
#
................................................................................
do_malloc_test 36 -sqlprep {
  CREATE TABLE t1(a, b);
  INSERT INTO t1 VALUES(1, 2);
  INSERT INTO t1 VALUES(3, 4);
} -sqlbody {
  SELECT test_agg_errmsg16(), group_concat(a) FROM t1
}
























# Ensure that no file descriptors were leaked.
do_test malloc-99.X {
  catch {db close}
  set sqlite_open_file_count
} {0}

puts open-file-count=$sqlite_open_file_count
finish_test







|







 







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









12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
# This file attempts to check the behavior of the SQLite library in 
# an out-of-memory situation. When compiled with -DSQLITE_DEBUG=1, 
# the SQLite library accepts a special command (sqlite3_memdebug_fail N C)
# which causes the N-th malloc to fail.  This special feature is used
# to see what happens in the library if a malloc were to really fail
# due to an out-of-memory situation.
#
# $Id: malloc.test,v 1.80 2009/06/22 05:43:24 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl


# Only run these tests if memory debugging is turned on.
#
................................................................................
do_malloc_test 36 -sqlprep {
  CREATE TABLE t1(a, b);
  INSERT INTO t1 VALUES(1, 2);
  INSERT INTO t1 VALUES(3, 4);
} -sqlbody {
  SELECT test_agg_errmsg16(), group_concat(a) FROM t1
}

# At one point, if an OOM occured immediately after obtaining a shared lock
# on the database file, the file remained locked. This test case ensures
# that bug has been fixed.
do_malloc_test 36 -tclprep {
  sqlite3 db2 test.db
  execsql {
    CREATE TABLE t1(a, b);
    INSERT INTO t1 VALUES(1, 2);
  } db2
} -sqlbody {
  SELECT * FROM t1;
} -cleanup {
  # Try to write to the database using connection [db2]. If connection [db]
  # has correctly released the shared lock, this write attempt should 
  # succeed. If [db] has not released the lock, this should hit an 
  # SQLITE_BUSY error.
  do_test malloc-36.$zRepeat.${::n}.unlocked {
    execsql {INSERT INTO t1 VALUES(3, 4)} db2
  } {}
  db2 close
}
catch { db2 close }

# Ensure that no file descriptors were leaked.
do_test malloc-99.X {
  catch {db close}
  set sqlite_open_file_count
} {0}

puts open-file-count=$sqlite_open_file_count
finish_test