/ Check-in [ffd3312b]
Login

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

Overview
Comment:Bug-fixes to get the two threadtest C programs working again. (CVS 1756)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ffd3312b66e2657c3431eab814aadec254af2403
User & Date: danielk1977 2004-06-29 07:45:33
Context
2004-06-29
08:59
Fix error reporting path for errors that occur while reading the database schema. (CVS 1757) check-in: 157db33e user: danielk1977 tags: trunk
07:45
Bug-fixes to get the two threadtest C programs working again. (CVS 1756) check-in: ffd3312b user: danielk1977 tags: trunk
03:29
Try to get threads working again on Linux. (CVS 1755) check-in: a8417cb8 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/build.c.

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
143
144
145
146
147
148
149





150
151
152
153
154
155
156
157
...
613
614
615
616
617
618
619

620
621
622
623
624
625
626
627
628

629
630
631
632
633
634
635
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.235 2004/06/28 01:11:47 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs
................................................................................
** where sqlite3FindTable() does not.
*/
Table *sqlite3LocateTable(Parse *pParse, const char *zName, const char *zDbase){
  Table *p;

  p = sqlite3FindTable(pParse->db, zName, zDbase);
  if( p==0 ){





    if( zDbase ){
      sqlite3ErrorMsg(pParse, "no such table: %s.%s", zDbase, zName);
    }else if( sqlite3FindTable(pParse->db, zName, 0)!=0 ){
      sqlite3ErrorMsg(pParse, "table \"%s\" is not in database \"%s\"",
         zName, zDbase);
    }else{
      sqlite3ErrorMsg(pParse, "no such table: %s", zName);
    }
................................................................................
  */
  if( isTemp && db->aDb[1].pBt==0 && !pParse->explain ){
    int rc = sqlite3BtreeFactory(db, 0, 0, MAX_PAGES, &db->aDb[1].pBt);
    if( rc!=SQLITE_OK ){
      sqlite3ErrorMsg(pParse, "unable to open a temporary database "
        "file for storing temporary tables");
      pParse->nErr++;

      sqliteFree(zName);
      return;
    }
    if( db->flags & !db->autoCommit ){
      rc = sqlite3BtreeBeginTrans(db->aDb[1].pBt, 1);
      if( rc!=SQLITE_OK ){
        sqlite3ErrorMsg(pParse, "unable to get a write lock on "
          "the temporary database file");
        sqliteFree(zName);

        return;
      }
    }
  }

  /* Make sure the new table name does not collide with an existing
  ** index or table name in the same database.  Issue an error message if







|







 







>
>
>
>
>
|







 







>









>







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
...
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.236 2004/06/29 07:45:33 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs
................................................................................
** where sqlite3FindTable() does not.
*/
Table *sqlite3LocateTable(Parse *pParse, const char *zName, const char *zDbase){
  Table *p;

  p = sqlite3FindTable(pParse->db, zName, zDbase);
  if( p==0 ){
    if( !(pParse->db->flags & SQLITE_Initialized) ){
      /* If the schema is not initialised at this point, it must be because
      ** the database is locked. */
      pParse->nErr++;
      pParse->rc = SQLITE_BUSY;
    }else if( zDbase ){
      sqlite3ErrorMsg(pParse, "no such table: %s.%s", zDbase, zName);
    }else if( sqlite3FindTable(pParse->db, zName, 0)!=0 ){
      sqlite3ErrorMsg(pParse, "table \"%s\" is not in database \"%s\"",
         zName, zDbase);
    }else{
      sqlite3ErrorMsg(pParse, "no such table: %s", zName);
    }
................................................................................
  */
  if( isTemp && db->aDb[1].pBt==0 && !pParse->explain ){
    int rc = sqlite3BtreeFactory(db, 0, 0, MAX_PAGES, &db->aDb[1].pBt);
    if( rc!=SQLITE_OK ){
      sqlite3ErrorMsg(pParse, "unable to open a temporary database "
        "file for storing temporary tables");
      pParse->nErr++;
      pParse->rc = rc;
      sqliteFree(zName);
      return;
    }
    if( db->flags & !db->autoCommit ){
      rc = sqlite3BtreeBeginTrans(db->aDb[1].pBt, 1);
      if( rc!=SQLITE_OK ){
        sqlite3ErrorMsg(pParse, "unable to get a write lock on "
          "the temporary database file");
        sqliteFree(zName);
        pParse->rc = rc;
        return;
      }
    }
  }

  /* Make sure the new table name does not collide with an existing
  ** index or table name in the same database.  Issue an error message if

Changes to src/main.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
81
82
83
84
85
86
87

88
89
90
91
92


93
94

95
96
97
98
99
100
101
102
103
...
114
115
116
117
118
119
120
121
122

123
124
125
126
127
128
129
...
192
193
194
195
196
197
198
199




200
201
202
203
204
205
206
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.237 2004/06/28 01:11:47 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information
................................................................................
      if( argv[3] && argv[3][0] ){
        /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
        ** But because db->init.busy is set to 1, no VDBE code is generated
        ** or executed.  All the parser does is build the internal data
        ** structures that describe the table, index, or view.
        */
        char *zErr;

        assert( db->init.busy );
        db->init.iDb = atoi(argv[4]);
        assert( db->init.iDb>=0 && db->init.iDb<db->nDb );
        db->init.newTnum = atoi(argv[2]);
        if( sqlite3_exec(db, argv[3], 0, 0, &zErr) ){


          corruptSchema(pData, zErr);
          sqlite3_free(zErr);

        }
        db->init.iDb = 0;
      }else{
        /* If the SQL column is blank it means this is an index that
        ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
        ** constraint for a CREATE TABLE.  The index should have already
        ** been created when we processed the CREATE TABLE.  All we have
        ** to do here is record the root page number for that index.
        */
................................................................................
          ** safely ignore the index on the permanent table.
          */
          /* Do Nothing */;
        }else{
          pIndex->tnum = atoi(argv[2]);
        }
      }
      break;
    }

    default: {
      /* This can not happen! */
      nErr = 1;
      assert( nErr==0 );
    }
  }
  return nErr;
................................................................................
  azArg[2] = "1";
  azArg[3] = zMasterSchema;
  sprintf(zDbNum, "%d", iDb);
  azArg[4] = zDbNum;
  azArg[5] = 0;
  initData.db = db;
  initData.pzErrMsg = pzErrMsg;
  sqlite3InitCallback(&initData, 5, (char **)azArg, 0);




  pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName);
  if( pTab ){
    pTab->readOnly = 1;
  }
  sqlite3SafetyOn(db);

  /* Create a cursor to hold the database open







|







 







>




|
>
>


>

<







 







<

>







 







|
>
>
>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

100
101
102
103
104
105
106
...
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131
132
...
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.238 2004/06/29 07:45:34 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information
................................................................................
      if( argv[3] && argv[3][0] ){
        /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
        ** But because db->init.busy is set to 1, no VDBE code is generated
        ** or executed.  All the parser does is build the internal data
        ** structures that describe the table, index, or view.
        */
        char *zErr;
        int rc;
        assert( db->init.busy );
        db->init.iDb = atoi(argv[4]);
        assert( db->init.iDb>=0 && db->init.iDb<db->nDb );
        db->init.newTnum = atoi(argv[2]);
        rc = sqlite3_exec(db, argv[3], 0, 0, &zErr);
        db->init.iDb = 0;
        if( SQLITE_OK!=rc ){
          corruptSchema(pData, zErr);
          sqlite3_free(zErr);
          return rc;
        }

      }else{
        /* If the SQL column is blank it means this is an index that
        ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
        ** constraint for a CREATE TABLE.  The index should have already
        ** been created when we processed the CREATE TABLE.  All we have
        ** to do here is record the root page number for that index.
        */
................................................................................
          ** safely ignore the index on the permanent table.
          */
          /* Do Nothing */;
        }else{
          pIndex->tnum = atoi(argv[2]);
        }
      }

    }
    break;
    default: {
      /* This can not happen! */
      nErr = 1;
      assert( nErr==0 );
    }
  }
  return nErr;
................................................................................
  azArg[2] = "1";
  azArg[3] = zMasterSchema;
  sprintf(zDbNum, "%d", iDb);
  azArg[4] = zDbNum;
  azArg[5] = 0;
  initData.db = db;
  initData.pzErrMsg = pzErrMsg;
  rc = sqlite3InitCallback(&initData, 5, (char **)azArg, 0);
  if( rc!=SQLITE_OK ){
    sqlite3SafetyOn(db);
    return rc;
  }
  pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName);
  if( pTab ){
    pTab->readOnly = 1;
  }
  sqlite3SafetyOn(db);

  /* Create a cursor to hold the database open

Changes to src/os_common.h.

40
41
42
43
44
45
46


47
48
49
50
51
52
53
#define SEEK(X)           last_page=(X)
#define TRACE1(X)         if( sqlite3_os_trace ) sqlite3DebugPrintf(X)
#define TRACE2(X,Y)       if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y)
#define TRACE3(X,Y,Z)     if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z)
#define TRACE4(X,Y,Z,A)   if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A)
#define TRACE5(X,Y,Z,A,B) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A,B)
#define TRACE6(X,Y,Z,A,B,C) if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C)


#else
#define TIMER_START
#define TIMER_END
#define SEEK(X)
#define TRACE1(X)
#define TRACE2(X,Y)
#define TRACE3(X,Y,Z)







>
>







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#define SEEK(X)           last_page=(X)
#define TRACE1(X)         if( sqlite3_os_trace ) sqlite3DebugPrintf(X)
#define TRACE2(X,Y)       if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y)
#define TRACE3(X,Y,Z)     if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z)
#define TRACE4(X,Y,Z,A)   if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A)
#define TRACE5(X,Y,Z,A,B) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A,B)
#define TRACE6(X,Y,Z,A,B,C) if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C)
#define TRACE7(X,Y,Z,A,B,C,D) \
    if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D)
#else
#define TIMER_START
#define TIMER_END
#define SEEK(X)
#define TRACE1(X)
#define TRACE2(X,Y)
#define TRACE3(X,Y,Z)

Changes to src/os_unix.c.

755
756
757
758
759
760
761


















762
763
764
765
766
767
768
...
824
825
826
827
828
829
830
831
832

833
834
835
836
837
838

839
840
841
842
843
844
845
...
952
953
954
955
956
957
958

959
960
961
962
963
964
965
966
...
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
  
  sqlite3OsLeaveMutex();
  TRACE3("TEST WR-LOCK %d %d\n", id->h, r);

  return r;
}



















/*
** Lock the file with the lock specified by parameter locktype - one
** of the following:
**
**     (1) SHARED_LOCK
**     (2) RESERVED_LOCK
**     (3) PENDING_LOCK
................................................................................
  */
  int rc = SQLITE_OK;
  struct lockInfo *pLock = id->pLock;
  struct flock lock;
  int s;

  assert( id->isOpen );
  TRACE6("LOCK %d %d was %d(%d,%d)\n",
          id->h, locktype, id->locktype, pLock->locktype, pLock->cnt);


  /* If there is already a lock of this type or more restrictive on the
  ** OsFile, do nothing. Don't use the end_lock: exit path, as
  ** sqlite3OsEnterMutex() hasn't been called yet.
  */
  if( id->locktype>=locktype ){

    return SQLITE_OK;
  }

  /* Make sure the locking sequence is correct
  */
  assert( id->locktype!=NO_LOCK || locktype==SHARED_LOCK );
  assert( locktype!=PENDING_LOCK );
................................................................................
  }else if( locktype==EXCLUSIVE_LOCK ){
    id->locktype = PENDING_LOCK;
    pLock->locktype = PENDING_LOCK;
  }

end_lock:
  sqlite3OsLeaveMutex();

  TRACE4("LOCK %d %d %s\n", id->h, locktype, rc==SQLITE_OK ? "ok" : "failed");
  return rc;
}

/*
** Lower the locking level on file descriptor id to locktype.  locktype
** must be either NO_LOCK or SHARED_LOCK.
**
................................................................................
** It is not possible for this routine to fail.
*/
int sqlite3OsUnlock(OsFile *id, int locktype){
  struct lockInfo *pLock;
  struct flock lock;

  assert( id->isOpen );
  TRACE6("UNLOCK %d %d was %d(%d,%d)\n",
          id->h, locktype, id->locktype, id->pLock->locktype, id->pLock->cnt);

  assert( locktype<=SHARED_LOCK );
  if( id->locktype<=locktype ){
    return SQLITE_OK;
  }
  sqlite3OsEnterMutex();
  pLock = id->pLock;







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







 







|
|
>






>







 







>
|







 







|
|







755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
...
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
...
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
...
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
  
  sqlite3OsLeaveMutex();
  TRACE3("TEST WR-LOCK %d %d\n", id->h, r);

  return r;
}

#ifdef SQLITE_DEBUG
/*
** Helper function for printing out trace information from debugging
** binaries. This returns the string represetation of the supplied
** integer lock-type.
*/
static const char * locktypeName(int locktype){
  switch( locktype ){
  case NO_LOCK: return "NONE";
  case SHARED_LOCK: return "SHARED";
  case RESERVED_LOCK: return "RESERVED";
  case PENDING_LOCK: return "PENDING";
  case EXCLUSIVE_LOCK: return "EXCLUSIVE";
  }
  return "ERROR";
}
#endif

/*
** Lock the file with the lock specified by parameter locktype - one
** of the following:
**
**     (1) SHARED_LOCK
**     (2) RESERVED_LOCK
**     (3) PENDING_LOCK
................................................................................
  */
  int rc = SQLITE_OK;
  struct lockInfo *pLock = id->pLock;
  struct flock lock;
  int s;

  assert( id->isOpen );
  TRACE7("LOCK %d %s was %s(%s,%d) pid=%d\n", id->h, locktypeName(locktype), 
      locktypeName(id->locktype), locktypeName(pLock->locktype), pLock->cnt
      ,getpid() );

  /* If there is already a lock of this type or more restrictive on the
  ** OsFile, do nothing. Don't use the end_lock: exit path, as
  ** sqlite3OsEnterMutex() hasn't been called yet.
  */
  if( id->locktype>=locktype ){
    TRACE3("LOCK %d %s ok (already held)\n", id->h, locktypeName(locktype));
    return SQLITE_OK;
  }

  /* Make sure the locking sequence is correct
  */
  assert( id->locktype!=NO_LOCK || locktype==SHARED_LOCK );
  assert( locktype!=PENDING_LOCK );
................................................................................
  }else if( locktype==EXCLUSIVE_LOCK ){
    id->locktype = PENDING_LOCK;
    pLock->locktype = PENDING_LOCK;
  }

end_lock:
  sqlite3OsLeaveMutex();
  TRACE4("LOCK %d %s %s\n", id->h, locktypeName(locktype), 
      rc==SQLITE_OK ? "ok" : "failed");
  return rc;
}

/*
** Lower the locking level on file descriptor id to locktype.  locktype
** must be either NO_LOCK or SHARED_LOCK.
**
................................................................................
** It is not possible for this routine to fail.
*/
int sqlite3OsUnlock(OsFile *id, int locktype){
  struct lockInfo *pLock;
  struct flock lock;

  assert( id->isOpen );
  TRACE7("UNLOCK %d %d was %d(%d,%d) pid=%d\n", id->h, locktype, id->locktype, 
      id->pLock->locktype, id->pLock->cnt, getpid());

  assert( locktype<=SHARED_LOCK );
  if( id->locktype<=locktype ){
    return SQLITE_OK;
  }
  sqlite3OsEnterMutex();
  pLock = id->pLock;

Changes to src/pragma.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
115
116
117
118
119
120
121
122

123

124
125
126
127
128
129
130
...
496
497
498
499
500
501
502

503
504
505
506
507
508
509
**    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.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.54 2004/06/26 19:35:30 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
# include "pager.h"
# include "btree.h"
................................................................................
  return 0;
}

/*
** Check to make sure the schema is loaded.  Return 1 if it is not.
*/
static int checkSchema(Parse *pParse){
  if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){

    pParse->nErr++;

    return 1;
  }
  return 0;
}

/*
** Process a pragma statement.  
................................................................................
        cnt++;
        for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
          if( sqlite3CheckIndexCollSeq(pParse, pIdx) ) goto pragma_out;
          sqlite3VdbeAddOp(v, OP_Integer, pIdx->tnum, 0);
          cnt++;
        }
      }

      sqlite3VdbeAddOp(v, OP_IntegrityCk, cnt, i);
      sqlite3VdbeAddOp(v, OP_Dup, 0, 1);
      addr = sqlite3VdbeOp3(v, OP_String8, 0, 0, "ok", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_Eq, 0, addr+6);
      sqlite3VdbeOp3(v, OP_String8, 0, 0,
         sqlite3MPrintf("*** in database %s ***\n", db->aDb[i].zName),
         P3_DYNAMIC);







|







 







|
>

>







 







>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
...
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
**    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.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.55 2004/06/29 07:45:34 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
# include "pager.h"
# include "btree.h"
................................................................................
  return 0;
}

/*
** Check to make sure the schema is loaded.  Return 1 if it is not.
*/
static int checkSchema(Parse *pParse){
  int rc = sqlite3ReadSchema(pParse->db, &pParse->zErrMsg);
  if( SQLITE_OK!=rc ){
    pParse->nErr++;
    pParse->rc = rc;
    return 1;
  }
  return 0;
}

/*
** Process a pragma statement.  
................................................................................
        cnt++;
        for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
          if( sqlite3CheckIndexCollSeq(pParse, pIdx) ) goto pragma_out;
          sqlite3VdbeAddOp(v, OP_Integer, pIdx->tnum, 0);
          cnt++;
        }
      }
      assert( cnt>0 );
      sqlite3VdbeAddOp(v, OP_IntegrityCk, cnt, i);
      sqlite3VdbeAddOp(v, OP_Dup, 0, 1);
      addr = sqlite3VdbeOp3(v, OP_String8, 0, 0, "ok", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_Eq, 0, addr+6);
      sqlite3VdbeOp3(v, OP_String8, 0, 0,
         sqlite3MPrintf("*** in database %s ***\n", db->aDb[i].zName),
         P3_DYNAMIC);

Changes to test/threadtest1.c.

258
259
260
261
262
263
264





265




266
267
268
269
270
271
272
  for(i=0; i<n; i++){
    char zBuf[200];
    sprintf(zBuf, "testdb-%d", (i+1)/2);
    unlink(zBuf);
  }
  for(i=0; i<n; i++){
    zFile = sqlite3_mprintf("%d.testdb-%d", i%2+1, (i+2)/2);





    unlink(zFile);




    pthread_create(&id, 0, worker_bee, (void*)zFile);
    pthread_detach(id);
  }
  pthread_mutex_lock(&lock);
  while( thread_cnt>0 ){
    pthread_cond_wait(&sig, &lock);
  }







>
>
>
>
>
|
>
>
>
>







258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
  for(i=0; i<n; i++){
    char zBuf[200];
    sprintf(zBuf, "testdb-%d", (i+1)/2);
    unlink(zBuf);
  }
  for(i=0; i<n; i++){
    zFile = sqlite3_mprintf("%d.testdb-%d", i%2+1, (i+2)/2);
    if( (i%2)==0 ){
      /* Remove both the database file and any old journal for the file
      ** being used by this thread and the next one. */
      char *zDb = &zFile[2];
      char *zJournal = sqlite3_mprintf("%s-journal", zDb);
      unlink(zDb);
      unlink(zJournal);
      free(zJournal);
    }
      
    pthread_create(&id, 0, worker_bee, (void*)zFile);
    pthread_detach(id);
  }
  pthread_mutex_lock(&lock);
  while( thread_cnt>0 ){
    pthread_cond_wait(&sig, &lock);
  }

Changes to test/threadtest2.c.

92
93
94
95
96
97
98
99





100
101
102
103
104
105
106
** Initialize the database and start the threads
*/
int main(int argc, char **argv){
  sqlite *db;
  int i, rc;
  pthread_t aThread[5];

  if( strcmp(DB_FILE,":memory:") ) unlink(DB_FILE);





  sqlite3_open(DB_FILE, &db);
  if( db==0 ){
    fprintf(stderr,"unable to initialize database\n");
    exit(1);
  }
  rc = sqlite3_exec(db, "CREATE TABLE t1(x);", 0,0,0);
  if( rc ){







|
>
>
>
>
>







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
** Initialize the database and start the threads
*/
int main(int argc, char **argv){
  sqlite *db;
  int i, rc;
  pthread_t aThread[5];

  if( strcmp(DB_FILE,":memory:") ){
    char *zJournal = sqlite3_mprintf("%s-journal", DB_FILE);
    unlink(DB_FILE);
    unlink(zJournal);
    free(zJournal);
  }  
  sqlite3_open(DB_FILE, &db);
  if( db==0 ){
    fprintf(stderr,"unable to initialize database\n");
    exit(1);
  }
  rc = sqlite3_exec(db, "CREATE TABLE t1(x);", 0,0,0);
  if( rc ){