SQLite

Check-in [1f28b7e47b]
Login

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

Overview
Comment:Get the quick.test script running with SQLITE_THREADSAFE enabled. (CVS 4269)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 1f28b7e47bba221c14a10a37e7425c9975bb2312
User & Date: drh 2007-08-22 11:41:18.000
Context
2007-08-22
18:54
Fix a bug in the logic for journaling pages when the device sector-size is greater than the page size. (CVS 4270) (check-in: b6399dff13 user: danielk1977 tags: trunk)
11:41
Get the quick.test script running with SQLITE_THREADSAFE enabled. (CVS 4269) (check-in: 1f28b7e47b user: drh tags: trunk)
11:22
Add code for the atomic-write optimisation. Disabled by default. (CVS 4268) (check-in: 581fadfe31 user: danielk1977 tags: trunk)
Changes
Unified Diff Show Whitespace Changes 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.408 2007/08/22 02:56:43 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"












|







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.409 2007/08/22 11:41:18 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"

1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
      pBt->xFreeSchema(pBt->pSchema);
    }
    sqlite3_free(pBt->pSchema);
    sqlite3_free(pBt);
  }

#ifndef SQLITE_OMIT_SHARED_CACHE
  else{
    assert( p->wantToLock==0 );
    assert( p->locked==0 );
    assert( p->sharable );
    if( p->pPrev ) p->pPrev->pNext = p->pNext;
    if( p->pNext ) p->pNext->pPrev = p->pPrev;
  }
#endif

  sqlite3_free(p);
  return SQLITE_OK;
}

#if SQLITE_THREADSAFE && !defined(SQLITE_OMIT_SHARED_CACHE)







<


<


<







1368
1369
1370
1371
1372
1373
1374

1375
1376

1377
1378

1379
1380
1381
1382
1383
1384
1385
      pBt->xFreeSchema(pBt->pSchema);
    }
    sqlite3_free(pBt->pSchema);
    sqlite3_free(pBt);
  }

#ifndef SQLITE_OMIT_SHARED_CACHE

    assert( p->wantToLock==0 );
    assert( p->locked==0 );

    if( p->pPrev ) p->pPrev->pNext = p->pNext;
    if( p->pNext ) p->pNext->pPrev = p->pPrev;

#endif

  sqlite3_free(p);
  return SQLITE_OK;
}

#if SQLITE_THREADSAFE && !defined(SQLITE_OMIT_SHARED_CACHE)
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495


#if SQLITE_THREADSAFE && !defined(SQLITE_OMIT_SHARED_CACHE)
/*
** Short-cuts for entering and leaving mutexes on a cursor.
*/
static void cursorLeave(BtCursor *p){
  sqlite3BtreeLeave(p->pBt);
}
static void cursorEnter(BtCursor *pCur){
  sqlite3BtreeEnter(pCur->pBt);
}
#else
# define cursorEnter(X)
# define cursorLeave(X)
#endif /* !SQLITE_OMIT_SHARED_CACHE */

/*







|


|







1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492


#if SQLITE_THREADSAFE && !defined(SQLITE_OMIT_SHARED_CACHE)
/*
** Short-cuts for entering and leaving mutexes on a cursor.
*/
static void cursorLeave(BtCursor *p){
  sqlite3BtreeLeave(p->pBtree);
}
static void cursorEnter(BtCursor *pCur){
  sqlite3BtreeEnter(pCur->pBtree);
}
#else
# define cursorEnter(X)
# define cursorLeave(X)
#endif /* !SQLITE_OMIT_SHARED_CACHE */

/*
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
      *pRes = 0;
      return rc;
    }
    do{
      if( sqlite3BtreeIsRootPage(pPage) ){
        *pRes = 1;
        pCur->eState = CURSOR_INVALID;
        cursorLeave(pCur);
        return SQLITE_OK;
      }
      sqlite3BtreeMoveToParent(pCur);
      pPage = pCur->pPage;
    }while( pCur->idx>=pPage->nCell );
    *pRes = 0;
    if( pPage->leafData ){







<







3752
3753
3754
3755
3756
3757
3758

3759
3760
3761
3762
3763
3764
3765
      *pRes = 0;
      return rc;
    }
    do{
      if( sqlite3BtreeIsRootPage(pPage) ){
        *pRes = 1;
        pCur->eState = CURSOR_INVALID;

        return SQLITE_OK;
      }
      sqlite3BtreeMoveToParent(pCur);
      pPage = pCur->pPage;
    }while( pCur->idx>=pPage->nCell );
    *pRes = 0;
    if( pPage->leafData ){
Changes to src/sqliteInt.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
** 2001 September 15
**
** 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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.596 2007/08/22 11:22:04 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
#include "sqliteLimit.h"


#if defined(SQLITE_TCL) || defined(TCLSH)













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
** 2001 September 15
**
** 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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.597 2007/08/22 11:41:18 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
#include "sqliteLimit.h"


#if defined(SQLITE_TCL) || defined(TCLSH)
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
** Older versions of SQLite used an optional THREADSAFE macro.
** We support that for legacy
*/
#if !defined(SQLITE_THREADSAFE)
#if defined(THREADSAFE)
# define SQLITE_THREADSAFE THREADSAFE
#else
# define SQLTIE_THREADSAFE 1
#endif
#endif

/*
** These #defines should enable >2GB file support on Posix if the
** underlying operating system supports it.  If the OS lacks
** large file support, or if the OS is windows, these should be no-ops.







|







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
** Older versions of SQLite used an optional THREADSAFE macro.
** We support that for legacy
*/
#if !defined(SQLITE_THREADSAFE)
#if defined(THREADSAFE)
# define SQLITE_THREADSAFE THREADSAFE
#else
# define SQLITE_THREADSAFE 1
#endif
#endif

/*
** These #defines should enable >2GB file support on Posix if the
** underlying operating system supports it.  If the OS lacks
** large file support, or if the OS is windows, these should be no-ops.
Changes to src/test4.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
** 2003 December 18
**
** 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.
**
*************************************************************************
** Code for testing the the SQLite library in a multithreaded environment.
**
** $Id: test4.c,v 1.20 2007/08/21 10:44:16 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#if defined(OS_UNIX) && OS_UNIX==1 && SQLITE_THREADSAFE
#include <stdlib.h>
#include <string.h>
#include <pthread.h>













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
** 2003 December 18
**
** 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.
**
*************************************************************************
** Code for testing the the SQLite library in a multithreaded environment.
**
** $Id: test4.c,v 1.21 2007/08/22 11:41:18 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#if defined(OS_UNIX) && OS_UNIX==1 && SQLITE_THREADSAFE
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
  i = parse_thread_id(interp, argv[1]);
  if( i<0 ) return TCL_ERROR;
  if( threadset[i].busy ){
    Tcl_AppendResult(interp, "thread ", argv[1], " is already running", 0);
    return TCL_ERROR;
  }
  threadset[i].busy = 1;
  sqliteFree(threadset[i].zFilename);
  threadset[i].zFilename = sqlite3StrDup(argv[2]);
  threadset[i].opnum = 1;
  threadset[i].completed = 0;
  rc = pthread_create(&x, 0, thread_main, &threadset[i]);
  if( rc ){
    Tcl_AppendResult(interp, "failed to create the thread", 0);
    sqliteFree(threadset[i].zFilename);
    threadset[i].busy = 0;
    return TCL_ERROR;
  }
  pthread_detach(x);
  return TCL_OK;
}








|






|







137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
  i = parse_thread_id(interp, argv[1]);
  if( i<0 ) return TCL_ERROR;
  if( threadset[i].busy ){
    Tcl_AppendResult(interp, "thread ", argv[1], " is already running", 0);
    return TCL_ERROR;
  }
  threadset[i].busy = 1;
  sqlite3_free(threadset[i].zFilename);
  threadset[i].zFilename = sqlite3StrDup(argv[2]);
  threadset[i].opnum = 1;
  threadset[i].completed = 0;
  rc = pthread_create(&x, 0, thread_main, &threadset[i]);
  if( rc ){
    Tcl_AppendResult(interp, "failed to create the thread", 0);
    sqlite3_free(threadset[i].zFilename);
    threadset[i].busy = 0;
    return TCL_ERROR;
  }
  pthread_detach(x);
  return TCL_OK;
}

195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
** Stop a thread.
*/
static void stop_thread(Thread *p){
  thread_wait(p);
  p->xOp = 0;
  p->opnum++;
  thread_wait(p);
  sqliteFree(p->zArg);
  p->zArg = 0;
  sqliteFree(p->zFilename);
  p->zFilename = 0;
  p->busy = 0;
}

/*
** Usage:  thread_halt ID
**







|

|







195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
** Stop a thread.
*/
static void stop_thread(Thread *p){
  thread_wait(p);
  p->xOp = 0;
  p->opnum++;
  thread_wait(p);
  sqlite3_free(p->zArg);
  p->zArg = 0;
  sqlite3_free(p->zFilename);
  p->zFilename = 0;
  p->busy = 0;
}

/*
** Usage:  thread_halt ID
**
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
  if( i<0 ) return TCL_ERROR;
  if( !threadset[i].busy ){
    Tcl_AppendResult(interp, "no such thread", 0);
    return TCL_ERROR;
  }
  thread_wait(&threadset[i]);
  threadset[i].xOp = do_compile;
  sqliteFree(threadset[i].zArg);
  threadset[i].zArg = sqlite3StrDup(argv[2]);
  threadset[i].opnum++;
  return TCL_OK;
}

/*
** This procedure runs in the thread to step the virtual machine.







|







471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
  if( i<0 ) return TCL_ERROR;
  if( !threadset[i].busy ){
    Tcl_AppendResult(interp, "no such thread", 0);
    return TCL_ERROR;
  }
  thread_wait(&threadset[i]);
  threadset[i].xOp = do_compile;
  sqlite3_free(threadset[i].zArg);
  threadset[i].zArg = sqlite3StrDup(argv[2]);
  threadset[i].opnum++;
  return TCL_OK;
}

/*
** This procedure runs in the thread to step the virtual machine.
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
  if( i<0 ) return TCL_ERROR;
  if( !threadset[i].busy ){
    Tcl_AppendResult(interp, "no such thread", 0);
    return TCL_ERROR;
  }
  thread_wait(&threadset[i]);
  threadset[i].xOp = do_finalize;
  sqliteFree(threadset[i].zArg);
  threadset[i].zArg = 0;
  threadset[i].opnum++;
  return TCL_OK;
}

/*
** Usage: thread_swap ID ID







|







566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
  if( i<0 ) return TCL_ERROR;
  if( !threadset[i].busy ){
    Tcl_AppendResult(interp, "no such thread", 0);
    return TCL_ERROR;
  }
  thread_wait(&threadset[i]);
  threadset[i].xOp = do_finalize;
  sqlite3_free(threadset[i].zArg);
  threadset[i].zArg = 0;
  threadset[i].opnum++;
  return TCL_OK;
}

/*
** Usage: thread_swap ID ID
Changes to src/test7.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the client/server version of the SQLite library.
** Derived from test4.c.
**
** $Id: test7.c,v 1.7 2007/08/21 10:44:16 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"

/*
** This test only works on UNIX with a SQLITE_THREADSAFE build that includes
** the SQLITE_SERVER option.







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the client/server version of the SQLite library.
** Derived from test4.c.
**
** $Id: test7.c,v 1.8 2007/08/22 11:41:18 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"

/*
** This test only works on UNIX with a SQLITE_THREADSAFE build that includes
** the SQLITE_SERVER option.
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
  i = parse_client_id(interp, argv[1]);
  if( i<0 ) return TCL_ERROR;
  if( threadset[i].busy ){
    Tcl_AppendResult(interp, "thread ", argv[1], " is already running", 0);
    return TCL_ERROR;
  }
  threadset[i].busy = 1;
  sqliteFree(threadset[i].zFilename);
  threadset[i].zFilename = sqlite3StrDup(argv[2]);
  threadset[i].opnum = 1;
  threadset[i].completed = 0;
  rc = pthread_create(&x, 0, client_main, &threadset[i]);
  if( rc ){
    Tcl_AppendResult(interp, "failed to create the thread", 0);
    sqliteFree(threadset[i].zFilename);
    threadset[i].busy = 0;
    return TCL_ERROR;
  }
  pthread_detach(x);
  sqlite3_server_start();
  return TCL_OK;
}







|






|







159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
  i = parse_client_id(interp, argv[1]);
  if( i<0 ) return TCL_ERROR;
  if( threadset[i].busy ){
    Tcl_AppendResult(interp, "thread ", argv[1], " is already running", 0);
    return TCL_ERROR;
  }
  threadset[i].busy = 1;
  sqlite3_free(threadset[i].zFilename);
  threadset[i].zFilename = sqlite3StrDup(argv[2]);
  threadset[i].opnum = 1;
  threadset[i].completed = 0;
  rc = pthread_create(&x, 0, client_main, &threadset[i]);
  if( rc ){
    Tcl_AppendResult(interp, "failed to create the thread", 0);
    sqlite3_free(threadset[i].zFilename);
    threadset[i].busy = 0;
    return TCL_ERROR;
  }
  pthread_detach(x);
  sqlite3_server_start();
  return TCL_OK;
}
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
** Stop a thread.
*/
static void stop_thread(Thread *p){
  client_wait(p);
  p->xOp = 0;
  p->opnum++;
  client_wait(p);
  sqliteFree(p->zArg);
  p->zArg = 0;
  sqliteFree(p->zFilename);
  p->zFilename = 0;
  p->busy = 0;
}

/*
** Usage:  client_halt ID
**







|

|







218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
** Stop a thread.
*/
static void stop_thread(Thread *p){
  client_wait(p);
  p->xOp = 0;
  p->opnum++;
  client_wait(p);
  sqlite3_free(p->zArg);
  p->zArg = 0;
  sqlite3_free(p->zFilename);
  p->zFilename = 0;
  p->busy = 0;
}

/*
** Usage:  client_halt ID
**
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
  if( i<0 ) return TCL_ERROR;
  if( !threadset[i].busy ){
    Tcl_AppendResult(interp, "no such thread", 0);
    return TCL_ERROR;
  }
  client_wait(&threadset[i]);
  threadset[i].xOp = do_compile;
  sqliteFree(threadset[i].zArg);
  threadset[i].zArg = sqlite3StrDup(argv[2]);
  threadset[i].opnum++;
  return TCL_OK;
}

/*
** This procedure runs in the thread to step the virtual machine.







|







502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
  if( i<0 ) return TCL_ERROR;
  if( !threadset[i].busy ){
    Tcl_AppendResult(interp, "no such thread", 0);
    return TCL_ERROR;
  }
  client_wait(&threadset[i]);
  threadset[i].xOp = do_compile;
  sqlite3_free(threadset[i].zArg);
  threadset[i].zArg = sqlite3StrDup(argv[2]);
  threadset[i].opnum++;
  return TCL_OK;
}

/*
** This procedure runs in the thread to step the virtual machine.
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
  if( i<0 ) return TCL_ERROR;
  if( !threadset[i].busy ){
    Tcl_AppendResult(interp, "no such thread", 0);
    return TCL_ERROR;
  }
  client_wait(&threadset[i]);
  threadset[i].xOp = do_finalize;
  sqliteFree(threadset[i].zArg);
  threadset[i].zArg = 0;
  threadset[i].opnum++;
  return TCL_OK;
}

/*
** This procedure runs in the thread to reset a virtual machine.







|







597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
  if( i<0 ) return TCL_ERROR;
  if( !threadset[i].busy ){
    Tcl_AppendResult(interp, "no such thread", 0);
    return TCL_ERROR;
  }
  client_wait(&threadset[i]);
  threadset[i].xOp = do_finalize;
  sqlite3_free(threadset[i].zArg);
  threadset[i].zArg = 0;
  threadset[i].opnum++;
  return TCL_OK;
}

/*
** This procedure runs in the thread to reset a virtual machine.
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
  if( i<0 ) return TCL_ERROR;
  if( !threadset[i].busy ){
    Tcl_AppendResult(interp, "no such thread", 0);
    return TCL_ERROR;
  }
  client_wait(&threadset[i]);
  threadset[i].xOp = do_reset;
  sqliteFree(threadset[i].zArg);
  threadset[i].zArg = 0;
  threadset[i].opnum++;
  return TCL_OK;
}

/*
** Usage: client_swap ID ID







|







641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
  if( i<0 ) return TCL_ERROR;
  if( !threadset[i].busy ){
    Tcl_AppendResult(interp, "no such thread", 0);
    return TCL_ERROR;
  }
  client_wait(&threadset[i]);
  threadset[i].xOp = do_reset;
  sqlite3_free(threadset[i].zArg);
  threadset[i].zArg = 0;
  threadset[i].opnum++;
  return TCL_OK;
}

/*
** Usage: client_swap ID ID