/ Check-in [1944d92b]
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 | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:1944d92b530d3bbcd31561063660de03d668af23
User & Date: danielk1977 2006-01-15 11:39:18
Context
2006-01-15
13:13
Fix a buffer-overrun that could occur after a malloc() failure. (CVS 2948) check-in: 66252221 user: danielk1977 tags: trunk
11:39
Rollback any open write-transaction when a shared-cache connection is closed. (CVS 2947) check-in: 1944d92b 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: ad8f12ca user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/btree.c.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
1693
1694
1695
1696
1697
1698
1699


1700
1701
1702
1703
1704
1705
1706
** 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.
................................................................................
    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.
  */







|







 







>
>







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
** 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.
................................................................................
    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
....
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
**
*************************************************************************
** 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>

/*
................................................................................

#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







|







 







|
|







|
|


10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
....
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
**
*************************************************************************
** 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>

/*
................................................................................

#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.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
636
637
638
639
640
641
642
643


















































































644
645
#
#    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}
do_test shared-9.3 {
  db close
  db2 close
} {}

} ; # End shared-9.*



















































































finish_test
sqlite3_enable_shared_cache $::enable_shared_cache







|







 








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


5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
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
#
#    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
................................................................................
} {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