SQLite

Check-in [1944d92b53]
Login

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

Overview
Comment:Rollback any open write-transaction when a shared-cache connection is closed. (CVS 2947)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 1944d92b530d3bbcd31561063660de03d668af23
User & Date: danielk1977 2006-01-15 11:39:18.000
Context
2006-01-15
13:13
Fix a buffer-overrun that could occur after a malloc() failure. (CVS 2948) (check-in: 662522218f user: danielk1977 tags: trunk)
11:39
Rollback any open write-transaction when a shared-cache connection is closed. (CVS 2947) (check-in: 1944d92b53 user: danielk1977 tags: trunk)
02:43
Closing a file from the wrong thread is harmless on most systems. (See ticket #1611) But on systems like RedHat9 with broken fcntl() locks, it leaks file descriptors. That is better than the alternative of prematurely breaking locks and causing database corruption. Nevertheless, it would be good if we could figure out a way to report errors when closing a file from the wrong thread. (CVS 2946) (check-in: ad8f12cad1 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/btree.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
** 2004 April 6
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.297 2006/01/13 11:22:07 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
** 2004 April 6
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.298 2006/01/15 11:39:18 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
1693
1694
1695
1696
1697
1698
1699


1700
1701
1702
1703
1704
1705
1706
    BtCursor *pTmp = pCur;
    pCur = pCur->pNext;
    if( pTmp->pBtree==p ){
      sqlite3BtreeCloseCursor(pTmp);
    }
  }



  sqliteFree(p);

#ifndef SQLITE_OMIT_SHARED_CACHE
  /* If there are still other outstanding references to the shared-btree
  ** structure, return now. The remainder of this procedure cleans 
  ** up the shared-btree.
  */







>
>







1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
    BtCursor *pTmp = pCur;
    pCur = pCur->pNext;
    if( pTmp->pBtree==p ){
      sqlite3BtreeCloseCursor(pTmp);
    }
  }

  /* Rollback any active transaction and free the handle structure */
  sqlite3BtreeRollback(p);
  sqliteFree(p);

#ifndef SQLITE_OMIT_SHARED_CACHE
  /* If there are still other outstanding references to the shared-btree
  ** structure, return now. The remainder of this procedure cleans 
  ** up the shared-btree.
  */
Changes to src/util.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.170 2006/01/13 06:33:24 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <stdarg.h>
#include <ctype.h>

/*







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.171 2006/01/15 11:39:18 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <stdarg.h>
#include <ctype.h>

/*
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370

#ifndef NDEBUG
/*
** This function sets a flag in the thread-specific-data structure that will
** cause an assert to fail if sqliteMalloc() or sqliteRealloc() is called.
*/
void sqlite3MallocDisallow(){
  assert(!sqlite3ThreadData()->mallocDisallowed);
  sqlite3ThreadData()->mallocDisallowed = 1;
}

/*
** This function clears the flag set in the thread-specific-data structure set
** by sqlite3MallocDisallow().
*/
void sqlite3MallocAllow(){
  assert(sqlite3ThreadData()->mallocDisallowed);
  sqlite3ThreadData()->mallocDisallowed = 0;
}
#endif







|
|







|
|


1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370

#ifndef NDEBUG
/*
** This function sets a flag in the thread-specific-data structure that will
** cause an assert to fail if sqliteMalloc() or sqliteRealloc() is called.
*/
void sqlite3MallocDisallow(){
  assert( sqlite3ThreadData()->mallocDisallowed>=0 );
  sqlite3ThreadData()->mallocDisallowed++;
}

/*
** This function clears the flag set in the thread-specific-data structure set
** by sqlite3MallocDisallow().
*/
void sqlite3MallocAllow(){
  assert( sqlite3ThreadData()->mallocDisallowed>0 );
  sqlite3ThreadData()->mallocDisallowed--;
}
#endif
Changes to test/shared.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 2005 December 30
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# $Id: shared.test,v 1.12 2006/01/14 08:02:29 danielk1977 Exp $

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

ifcapable !shared_cache {
  finish_test











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 2005 December 30
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# $Id: shared.test,v 1.13 2006/01/15 11:39:18 danielk1977 Exp $

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

ifcapable !shared_cache {
  finish_test
636
637
638
639
640
641
642
643


















































































644
645
} {1 2 3}
do_test shared-9.3 {
  db close
  db2 close
} {}

} ; # End shared-9.*



















































































finish_test
sqlite3_enable_shared_cache $::enable_shared_cache








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


636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
} {1 2 3}
do_test shared-9.3 {
  db close
  db2 close
} {}

} ; # End shared-9.*

#---------------------------------------------------------------------------
# The following tests - shared-10.* - test that the library behaves 
# correctly when a connection to a shared-cache is closed. 
#
do_test shared-10.1 {
  # Create a small sample database with two connections to it (db and db2).
  file delete -force test.db
  sqlite3 db  test.db
  sqlite3 db2 test.db
  execsql {
    CREATE TABLE ab(a PRIMARY KEY, b);
    CREATE TABLE de(d PRIMARY KEY, e);
    INSERT INTO ab VALUES('Chiang Mai', 100000);
    INSERT INTO ab VALUES('Bangkok', 8000000);
    INSERT INTO de VALUES('Ubon', 120000);
    INSERT INTO de VALUES('Khon Kaen', 200000);
  }
} {}
do_test shared-10.2 {
  # Open a read-transaction with the first connection, a write-transaction
  # with the second.
  execsql {
    BEGIN;
    SELECT * FROM ab;
  }
  execsql {
    BEGIN;
    INSERT INTO de VALUES('Pataya', 30000);
  } db2
} {}
do_test shared-10.3 {
  # An external connection should be able to read the database, but not
  # prepare a write operation.
  sqlite3 db3 ./test.db
  execsql {
    SELECT * FROM ab;
  } db3
  catchsql {
    BEGIN;
    INSERT INTO de VALUES('Pataya', 30000);
  } db3
} {1 {database is locked}}
do_test shared-10.4 {
  # Close the connection with the write-transaction open
  db2 close
} {}
do_test shared-10.5 {
  # Test that the db2 transaction has been automatically rolled back.
  # If it has not the ('Pataya', 30000) entry will still be in the table.
  execsql {
    SELECT * FROM de;
  }
} {Ubon 120000 {Khon Kaen} 200000}
do_test shared-10.5 {
  # Closing db2 should have dropped the shared-cache back to a read-lock.
  # So db3 should be able to prepare a write...
  catchsql {INSERT INTO de VALUES('Pataya', 30000);} db3
} {0 {}}
do_test shared-10.6 {
  # ... but not commit it.
  catchsql {COMMIT} db3
} {1 {database is locked}}
do_test shared-10.7 {
  # Commit the (read-only) db transaction. Check via db3 to make sure the 
  # contents of table "de" are still as they should be.
  execsql {
    COMMIT;
  }
  execsql {
    SELECT * FROM de;
  } db3
} {Ubon 120000 {Khon Kaen} 200000 Pataya 30000}
do_test shared-10.9 {
  # Commit the external transaction.
  catchsql {COMMIT} db3
} {0 {}}
integrity_check shared-10.10
do_test shared-10.11 {
  db close
  db3 close
} {}

finish_test
sqlite3_enable_shared_cache $::enable_shared_cache