/ Check-in [f84550be]
Login

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

Overview
Comment:The shared_err test runs with no errors. But a potential deadlock has been discovered and is still unfixed. (CVS 4317)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: f84550be0a0c9e5859b852863b9a8f8ed3fd6919
User & Date: drh 2007-08-28 23:28:07
Original Comment: The shared_err test runs with no errors. But a potential deadlock has been discovered and is still unfixed. (CVS 4317)
Original User & Date: drh 2007-08-28 23:28:08
Context
2007-08-28
23:28
The shared_err test runs with no errors. But a potential deadlock has been discovered and is still unfixed. (CVS 4318) check-in: f093a0d7 user: drh tags: trunk
23:28
The shared_err test runs with no errors. But a potential deadlock has been discovered and is still unfixed. (CVS 4317) check-in: f84550be user: drh tags: trunk
22:24
Clean up the locking in the btree logic. (CVS 4316) check-in: 967ab229 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/btmutex.c.

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
...
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
...
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
**
**    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: btmutex.c,v 1.2 2007/08/28 16:44:20 drh Exp $
**
** This file contains code used to implement mutexes on Btree objects.
** This code really belongs in btree.c.  But btree.c is getting too
** big and we want to break it down some.  This packaged seemed like
** a good breakout.
*/
#include "btreeInt.h"
................................................................................
      sqlite3_mutex_leave(p->pBt->mutex);
      p->locked = 0;
    }
  }
}

/*
** Potentially dd a new Btree pointer to a BtreeMutexSet.
** Really only add the Btree if it can possibly be shared with
** another database connection.
**
** The Btrees are kept in sorted order by pBtree->pBt.  That
** way when we go to enter all the mutexes, we can enter them
** in order without every having to backup and retry and without
** worrying about deadlock.
**
** The number of shared btrees will always be small (usually 0 or 1)
** so an insertion sort is an adequate algorithm here.
*/
void sqlite3BtreeMutexSetInsert(BtreeMutexSet *pSet, Btree *pBtree){
  int i, j;
  BtShared *pBt;
  if( !pBtree->sharable ) return;
#ifndef NDEBUG
  {
    for(i=0; i<pSet->nMutex; i++){
      assert( pSet->aBtree[i]!=pBtree );
................................................................................
      return;
    }
  }
  pSet->aBtree[pSet->nMutex++] = pBtree;
}

/*
** Enter the mutex of every btree in the set.  This routine is
** called at the beginning of sqlite3VdbeExec().  The mutexes are
** exited at the end of the same function.
*/
void sqlite3BtreeMutexSetEnter(BtreeMutexSet *pSet){
  int i;
  for(i=0; i<pSet->nMutex; i++){
    Btree *p = pSet->aBtree[i];
    /* Some basic sanity checking */
    assert( i==0 || pSet->aBtree[i-1]->pBt<p->pBt );
    assert( !p->locked || p->wantToLock>0 );
    assert( p->sharable );
................................................................................
      sqlite3_mutex_enter(p->pBt->mutex);
      p->locked = 1;
    }
  }
}

/*
** Leave the mutex of every btree in the set.
*/
void sqlite3BtreeMutexSetLeave(BtreeMutexSet *pSet){
  int i;
  for(i=0; i<pSet->nMutex; i++){
    Btree *p = pSet->aBtree[i];
    /* Some basic sanity checking */
    assert( i==0 || pSet->aBtree[i-1]->pBt<p->pBt );
    assert( p->locked );
    assert( p->sharable );







|







 







|











|







 







|



|







 







|

|







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
...
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
...
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
**
**    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: btmutex.c,v 1.3 2007/08/28 23:28:08 drh Exp $
**
** This file contains code used to implement mutexes on Btree objects.
** This code really belongs in btree.c.  But btree.c is getting too
** big and we want to break it down some.  This packaged seemed like
** a good breakout.
*/
#include "btreeInt.h"
................................................................................
      sqlite3_mutex_leave(p->pBt->mutex);
      p->locked = 0;
    }
  }
}

/*
** Potentially dd a new Btree pointer to a BtreeMutexArray.
** Really only add the Btree if it can possibly be shared with
** another database connection.
**
** The Btrees are kept in sorted order by pBtree->pBt.  That
** way when we go to enter all the mutexes, we can enter them
** in order without every having to backup and retry and without
** worrying about deadlock.
**
** The number of shared btrees will always be small (usually 0 or 1)
** so an insertion sort is an adequate algorithm here.
*/
void sqlite3BtreeMutexArrayInsert(BtreeMutexArray *pSet, Btree *pBtree){
  int i, j;
  BtShared *pBt;
  if( !pBtree->sharable ) return;
#ifndef NDEBUG
  {
    for(i=0; i<pSet->nMutex; i++){
      assert( pSet->aBtree[i]!=pBtree );
................................................................................
      return;
    }
  }
  pSet->aBtree[pSet->nMutex++] = pBtree;
}

/*
** Enter the mutex of every btree in the array.  This routine is
** called at the beginning of sqlite3VdbeExec().  The mutexes are
** exited at the end of the same function.
*/
void sqlite3BtreeMutexArrayEnter(BtreeMutexArray *pSet){
  int i;
  for(i=0; i<pSet->nMutex; i++){
    Btree *p = pSet->aBtree[i];
    /* Some basic sanity checking */
    assert( i==0 || pSet->aBtree[i-1]->pBt<p->pBt );
    assert( !p->locked || p->wantToLock>0 );
    assert( p->sharable );
................................................................................
      sqlite3_mutex_enter(p->pBt->mutex);
      p->locked = 1;
    }
  }
}

/*
** Leave the mutex of every btree in the group.
*/
void sqlite3BtreeMutexArrayLeave(BtreeMutexArray *pSet){
  int i;
  for(i=0; i<pSet->nMutex; i++){
    Btree *p = pSet->aBtree[i];
    /* Some basic sanity checking */
    assert( i==0 || pSet->aBtree[i-1]->pBt<p->pBt );
    assert( p->locked );
    assert( p->sharable );

Changes to src/btree.c.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
2416
2417
2418
2419
2420
2421
2422


2423

2424
2425
2426
2427
2428
2429
2430
** 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.414 2007/08/28 22:24:35 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
** Including a description of file format and an overview of operation.
*/
#include "btreeInt.h"

................................................................................
    ** the cache may be internally inconsistent (not contain valid trees) so
    ** we cannot simply return the error to the caller. Instead, abort 
    ** all queries that may be using any of the cursors that failed to save.
    */
    while( pBt->pCursor ){
      sqlite3 *db = pBt->pCursor->pBtree->pSqlite;
      if( db ){


        sqlite3AbortOtherActiveVdbes(db, 0);

      }
    }
  }
#endif
  btreeIntegrity(p);
  unlockAllTables(p);








|







 







>
>

>







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
** 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.415 2007/08/28 23:28:08 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
** Including a description of file format and an overview of operation.
*/
#include "btreeInt.h"

................................................................................
    ** the cache may be internally inconsistent (not contain valid trees) so
    ** we cannot simply return the error to the caller. Instead, abort 
    ** all queries that may be using any of the cursors that failed to save.
    */
    while( pBt->pCursor ){
      sqlite3 *db = pBt->pCursor->pBtree->pSqlite;
      if( db ){
        /**** FIX ME: This can deadlock ****/
        sqlite3_mutex_enter(db->mutex);
        sqlite3AbortOtherActiveVdbes(db, 0);
        sqlite3_mutex_leave(db->mutex);
      }
    }
  }
#endif
  btreeIntegrity(p);
  unlockAllTables(p);

Changes to src/btree.h.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
...
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite B-Tree file
** subsystem.  See comments in the source code for a detailed description
** of what each interface routine does.
**
** @(#) $Id: btree.h,v 1.87 2007/08/28 02:27:52 drh Exp $
*/
#ifndef _BTREE_H_
#define _BTREE_H_

/* TODO: This definition is just included so other modules compile. It
** needs to be revisited.
*/
................................................................................

/*
** Forward declarations of structure
*/
typedef struct Btree Btree;
typedef struct BtCursor BtCursor;
typedef struct BtShared BtShared;
typedef struct BtreeMutexSet BtreeMutexSet;

/*
** This structure records all of the Btrees that need to hold
** a mutex before we enter sqlite3VdbeExec().  The Btrees are
** are placed in aBtree[] in order of aBtree[]->pBt.  That way,
** we can always lock and unlock them all quickly.
*/
struct BtreeMutexSet {
  int nMutex;
  Btree *aBtree[SQLITE_MAX_ATTACHED+1];
};


int sqlite3BtreeOpen(
  const char *zFilename,   /* Name of database file to open */
................................................................................
#ifdef SQLITE_TEST
int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
void sqlite3BtreeCursorList(Btree*);
int sqlite3BtreePageDump(Btree*, int, int recursive);
#endif

#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE
  void sqlite3BtreeMutexSetEnter(BtreeMutexSet*);
  void sqlite3BtreeMutexSetLeave(BtreeMutexSet*);
  void sqlite3BtreeMutexSetInsert(BtreeMutexSet*, Btree*);
#else
# define sqlite3BtreeMutexSetEnter(X)
# define sqlite3BtreeMutexSetLeave(X)
# define sqlite3BtreeMutexSetInsert(X,Y)
#endif



#endif /* _BTREE_H_ */







|







 







|







|







 







|
|
|

|
|
|





9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
...
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite B-Tree file
** subsystem.  See comments in the source code for a detailed description
** of what each interface routine does.
**
** @(#) $Id: btree.h,v 1.88 2007/08/28 23:28:08 drh Exp $
*/
#ifndef _BTREE_H_
#define _BTREE_H_

/* TODO: This definition is just included so other modules compile. It
** needs to be revisited.
*/
................................................................................

/*
** Forward declarations of structure
*/
typedef struct Btree Btree;
typedef struct BtCursor BtCursor;
typedef struct BtShared BtShared;
typedef struct BtreeMutexArray BtreeMutexArray;

/*
** This structure records all of the Btrees that need to hold
** a mutex before we enter sqlite3VdbeExec().  The Btrees are
** are placed in aBtree[] in order of aBtree[]->pBt.  That way,
** we can always lock and unlock them all quickly.
*/
struct BtreeMutexArray {
  int nMutex;
  Btree *aBtree[SQLITE_MAX_ATTACHED+1];
};


int sqlite3BtreeOpen(
  const char *zFilename,   /* Name of database file to open */
................................................................................
#ifdef SQLITE_TEST
int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
void sqlite3BtreeCursorList(Btree*);
int sqlite3BtreePageDump(Btree*, int, int recursive);
#endif

#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE
  void sqlite3BtreeMutexArrayEnter(BtreeMutexArray*);
  void sqlite3BtreeMutexArrayLeave(BtreeMutexArray*);
  void sqlite3BtreeMutexArrayInsert(BtreeMutexArray*, Btree*);
#else
# define sqlite3BtreeMutexArrayEnter(X)
# define sqlite3BtreeMutexArrayLeave(X)
# define sqlite3BtreeMutexArrayInsert(X,Y)
#endif



#endif /* _BTREE_H_ */

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
....
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.645 2007/08/28 02:27:52 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <math.h>
#include "vdbeInt.h"

/*
................................................................................
#ifndef NDEBUG
  Mem *pStackLimit;
#endif

  if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;
  assert( db->magic==SQLITE_MAGIC_BUSY );
  pTos = p->pTos;
  sqlite3BtreeMutexSetEnter(&p->mtxSet);
  if( p->rc==SQLITE_NOMEM ){
    /* This happens if a malloc() inside a call to sqlite3_column_text() or
    ** sqlite3_column_text16() failed.  */
    goto no_mem;
  }
  assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
  p->rc = SQLITE_OK;
................................................................................
  sqlite3VdbeHalt(p);
  p->pTos = pTos;

  /* This is the only way out of this procedure.  We have to
  ** release the mutexes on btrees that were acquired at the
  ** top. */
vdbe_return:
  sqlite3BtreeMutexSetLeave(&p->mtxSet);
  return rc;

  /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH
  ** is encountered.
  */
too_big:
  sqlite3SetString(&p->zErrMsg, "string or blob too big", (char*)0);







|







 







|







 







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
....
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.646 2007/08/28 23:28:08 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <math.h>
#include "vdbeInt.h"

/*
................................................................................
#ifndef NDEBUG
  Mem *pStackLimit;
#endif

  if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;
  assert( db->magic==SQLITE_MAGIC_BUSY );
  pTos = p->pTos;
  sqlite3BtreeMutexArrayEnter(&p->aMutex);
  if( p->rc==SQLITE_NOMEM ){
    /* This happens if a malloc() inside a call to sqlite3_column_text() or
    ** sqlite3_column_text16() failed.  */
    goto no_mem;
  }
  assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
  p->rc = SQLITE_OK;
................................................................................
  sqlite3VdbeHalt(p);
  p->pTos = pTos;

  /* This is the only way out of this procedure.  We have to
  ** release the mutexes on btrees that were acquired at the
  ** top. */
vdbe_return:
  sqlite3BtreeMutexArrayLeave(&p->aMutex);
  return rc;

  /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH
  ** is encountered.
  */
too_big:
  sqlite3SetString(&p->zErrMsg, "string or blob too big", (char*)0);

Changes to src/vdbeInt.h.

329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
  u8 aborted;             /* True if ROLLBACK in another VM causes an abort */
  u8 expired;             /* True if the VM needs to be recompiled */
  u8 minWriteFileFormat;  /* Minimum file format for writable database files */
  u8 inVtabMethod;        /* See comments above */
  int nChange;            /* Number of db changes made since last reset */
  i64 startTime;          /* Time when query started - used for profiling */
  int btreeMask;          /* Bitmask of db->aDb[] entries referenced */
  BtreeMutexSet mtxSet;   /* Set of Btree mutexes */
  int nSql;             /* Number of bytes in zSql */
  char *zSql;           /* Text of the SQL statement that generated this */
#ifdef SQLITE_DEBUG
  FILE *trace;        /* Write an execution trace here, if not NULL */
#endif
  int openedStatement;  /* True if this VM has opened a statement journal */
#ifdef SQLITE_SSE







|







329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
  u8 aborted;             /* True if ROLLBACK in another VM causes an abort */
  u8 expired;             /* True if the VM needs to be recompiled */
  u8 minWriteFileFormat;  /* Minimum file format for writable database files */
  u8 inVtabMethod;        /* See comments above */
  int nChange;            /* Number of db changes made since last reset */
  i64 startTime;          /* Time when query started - used for profiling */
  int btreeMask;          /* Bitmask of db->aDb[] entries referenced */
  BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */
  int nSql;             /* Number of bytes in zSql */
  char *zSql;           /* Text of the SQL statement that generated this */
#ifdef SQLITE_DEBUG
  FILE *trace;        /* Write an execution trace here, if not NULL */
#endif
  int openedStatement;  /* True if this VM has opened a statement journal */
#ifdef SQLITE_SSE

Changes to src/vdbeaux.c.

663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
....
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
....
1529
1530
1531
1532
1533
1534
1535








1536
1537
1538
1539
1540
1541
1542
**
*/
void sqlite3VdbeUsesBtree(Vdbe *p, int i, Btree *pBtree){
  assert( i>=0 && i<p->db->nDb );
  assert( i<sizeof(p->btreeMask)*8 );
  assert( p->db->aDb[i].pBt==pBtree );
  p->btreeMask |= 1<<i;
  sqlite3BtreeMutexSetInsert(&p->mtxSet, pBtree);
}


#if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
/*
** Print a single opcode.  This routine is used for debugging only.
*/
................................................................................
** This routine is the only way to move the state of a VM from
** SQLITE_MAGIC_RUN to SQLITE_MAGIC_HALT.
**
** Return an error code.  If the commit could not complete because of
** lock contention, return SQLITE_BUSY.  If SQLITE_BUSY is returned, it
** means the close did not happen and needs to be repeated.
*/
int sqlite3VdbeHalt(Vdbe *p){
  sqlite3 *db = p->db;
  int i;
  int (*xFunc)(Btree *pBt) = 0;  /* Function to call on each btree backend */
  int isSpecialError;            /* Set to true if SQLITE_NOMEM or IOERR */

  /* This function contains the logic that determines if a statement or
  ** transaction will be committed or rolled back as a result of the
................................................................................
    db->activeVdbeCnt--;
  }
  p->magic = VDBE_MAGIC_HALT;
  checkActiveVdbeCnt(db);

  return SQLITE_OK;
}









/*
** Each VDBE holds the result of the most recent sqlite3_step() call
** in p->rc.  This routine sets that result back to SQLITE_OK.
*/
void sqlite3VdbeResetStepResult(Vdbe *p){
  p->rc = SQLITE_OK;







|







 







|







 







>
>
>
>
>
>
>
>







663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
....
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
....
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
**
*/
void sqlite3VdbeUsesBtree(Vdbe *p, int i, Btree *pBtree){
  assert( i>=0 && i<p->db->nDb );
  assert( i<sizeof(p->btreeMask)*8 );
  assert( p->db->aDb[i].pBt==pBtree );
  p->btreeMask |= 1<<i;
  sqlite3BtreeMutexArrayInsert(&p->aMutex, pBtree);
}


#if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
/*
** Print a single opcode.  This routine is used for debugging only.
*/
................................................................................
** This routine is the only way to move the state of a VM from
** SQLITE_MAGIC_RUN to SQLITE_MAGIC_HALT.
**
** Return an error code.  If the commit could not complete because of
** lock contention, return SQLITE_BUSY.  If SQLITE_BUSY is returned, it
** means the close did not happen and needs to be repeated.
*/
static int sqlite3VdbeHaltLocked(Vdbe *p){
  sqlite3 *db = p->db;
  int i;
  int (*xFunc)(Btree *pBt) = 0;  /* Function to call on each btree backend */
  int isSpecialError;            /* Set to true if SQLITE_NOMEM or IOERR */

  /* This function contains the logic that determines if a statement or
  ** transaction will be committed or rolled back as a result of the
................................................................................
    db->activeVdbeCnt--;
  }
  p->magic = VDBE_MAGIC_HALT;
  checkActiveVdbeCnt(db);

  return SQLITE_OK;
}
int sqlite3VdbeHalt(Vdbe *p){
  int rc;
  sqlite3BtreeMutexArrayEnter(&p->aMutex);
  rc = sqlite3VdbeHaltLocked(p);
  sqlite3BtreeMutexArrayLeave(&p->aMutex);
  return rc;
}


/*
** Each VDBE holds the result of the most recent sqlite3_step() call
** in p->rc.  This routine sets that result back to SQLITE_OK.
*/
void sqlite3VdbeResetStepResult(Vdbe *p){
  p->rc = SQLITE_OK;

Changes to test/shared_err.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#
#***********************************************************************
#
# The focus of the tests in this file are IO errors that occur in a shared
# cache context. What happens to connection B if one connection A encounters
# an IO-error whilst reading or writing the file-system?
#
# $Id: shared_err.test,v 1.13 2007/08/28 22:24:35 drh Exp $

proc skip {args} {}


set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
................................................................................
  execsql {COMMIT} db2
  set ::DB2 [sqlite3_connection_pointer db2]
  set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY]
  sqlite3_step $::STMT       ;# Cursor points at 000.000.000.000
  sqlite3_step $::STMT       ;# Cursor points at 001.001.001.001

} -tclbody {
btree_breakpoint
  execsql {
    BEGIN;
    INSERT INTO t1 VALUES('201.201.201.201.201', NULL);
    UPDATE t1 SET a = '202.202.202.202.202' WHERE a LIKE '201%';
    COMMIT;
  }
} -cleanup {







|







 







<







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
152
153
154
155
156
157
158

159
160
161
162
163
164
165
#
#***********************************************************************
#
# The focus of the tests in this file are IO errors that occur in a shared
# cache context. What happens to connection B if one connection A encounters
# an IO-error whilst reading or writing the file-system?
#
# $Id: shared_err.test,v 1.14 2007/08/28 23:28:09 drh Exp $

proc skip {args} {}


set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
................................................................................
  execsql {COMMIT} db2
  set ::DB2 [sqlite3_connection_pointer db2]
  set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY]
  sqlite3_step $::STMT       ;# Cursor points at 000.000.000.000
  sqlite3_step $::STMT       ;# Cursor points at 001.001.001.001

} -tclbody {

  execsql {
    BEGIN;
    INSERT INTO t1 VALUES('201.201.201.201.201', NULL);
    UPDATE t1 SET a = '202.202.202.202.202' WHERE a LIKE '201%';
    COMMIT;
  }
} -cleanup {