xref: /sqlite-3.40.0/src/test_async.c (revision d230f648)
1 /*
2 ** 2005 December 14
3 **
4 ** The author disclaims copyright to this source code.  In place of
5 ** a legal notice, here is a blessing:
6 **
7 **    May you do good and not evil.
8 **    May you find forgiveness for yourself and forgive others.
9 **    May you share freely, never taking more than you give.
10 **
11 *************************************************************************
12 **
13 ** This file contains an example implementation of an asynchronous IO
14 ** backend for SQLite.
15 **
16 ** WHAT IS ASYNCHRONOUS I/O?
17 **
18 ** With asynchronous I/O, write requests are handled by a separate thread
19 ** running in the background.  This means that the thread that initiates
20 ** a database write does not have to wait for (sometimes slow) disk I/O
21 ** to occur.  The write seems to happen very quickly, though in reality
22 ** it is happening at its usual slow pace in the background.
23 **
24 ** Asynchronous I/O appears to give better responsiveness, but at a price.
25 ** You lose the Durable property.  With the default I/O backend of SQLite,
26 ** once a write completes, you know that the information you wrote is
27 ** safely on disk.  With the asynchronous I/O, this is no the case.  If
28 ** your program crashes or if you take a power lose after the database
29 ** write but before the asynchronous write thread has completed, then the
30 ** database change might never make it to disk and the next user of the
31 ** database might not see your change.
32 **
33 ** You lose Durability with asynchronous I/O, but you still retain the
34 ** other parts of ACID:  Atomic,  Consistent, and Isolated.  Many
35 ** appliations get along fine without the Durablity.
36 **
37 ** HOW IT WORKS
38 **
39 ** Asynchronous I/O works by overloading the OS-layer disk I/O routines
40 ** with modified versions that store the data to be written in queue of
41 ** pending write operations.  Look at the asyncEnable() subroutine to see
42 ** how overloading works.  Six os-layer routines are overloaded:
43 **
44 **     sqlite3OsOpenReadWrite;
45 **     sqlite3OsOpenReadOnly;
46 **     sqlite3OsOpenExclusive;
47 **     sqlite3OsDelete;
48 **     sqlite3OsFileExists;
49 **     sqlite3OsSyncDirectory;
50 **
51 ** The original implementations of these routines are saved and are
52 ** used by the writer thread to do the real I/O.  The substitute
53 ** implementations typically put the I/O operation on a queue
54 ** to be handled later by the writer thread, though read operations
55 ** must be handled right away, obviously.
56 **
57 ** Asynchronous I/O is disabled by setting the os-layer interface routines
58 ** back to their original values.
59 **
60 ** LIMITATIONS
61 **
62 ** This demonstration code is deliberately kept simple in order to keep
63 ** the main ideas clear and easy to understand.  Real applications that
64 ** want to do asynchronous I/O might want to add additional capabilities.
65 ** For example, in this demonstration if writes are happening at a steady
66 ** stream that exceeds the I/O capability of the background writer thread,
67 ** the queue of pending write operations will grow without bound until we
68 ** run out of memory.  Users of this technique may want to keep track of
69 ** the quantity of pending writes and stop accepting new write requests
70 ** when the buffer gets to be too big.
71 */
72 
73 #include "sqliteInt.h"
74 #include "os.h"
75 #include <tcl.h>
76 
77 /* If the THREADSAFE macro is not set, assume that it is turned off. */
78 #ifndef THREADSAFE
79 # define THREADSAFE 0
80 #endif
81 
82 /*
83 ** This test uses pthreads and hence only works on unix and with
84 ** a threadsafe build of SQLite.  It also requires that the redefinable
85 ** I/O feature of SQLite be turned on.  This feature is turned off by
86 ** default.  If a required element is missing, almost all of the code
87 ** in this file is commented out.
88 */
89 #if OS_UNIX && THREADSAFE && defined(SQLITE_ENABLE_REDEF_IO)
90 
91 /*
92 ** This demo uses pthreads.  If you do not have a pthreads implementation
93 ** for your operating system, you will need to recode the threading
94 ** logic.
95 */
96 #include <pthread.h>
97 #include <sched.h>
98 
99 /* Useful macros used in several places */
100 #define MIN(x,y) ((x)<(y)?(x):(y))
101 #define MAX(x,y) ((x)>(y)?(x):(y))
102 
103 /* Forward references */
104 typedef struct AsyncWrite AsyncWrite;
105 typedef struct AsyncFile AsyncFile;
106 
107 /* Enable for debugging */
108 static int sqlite3async_trace = 0;
109 # define ASYNC_TRACE(X) if( sqlite3async_trace ) asyncTrace X
110 static void asyncTrace(const char *zFormat, ...){
111   char *z;
112   va_list ap;
113   va_start(ap, zFormat);
114   z = sqlite3_vmprintf(zFormat, ap);
115   va_end(ap);
116   fprintf(stderr, "[%d] %s", (int)pthread_self(), z);
117   sqlite3_free(z);
118 }
119 
120 /*
121 ** THREAD SAFETY NOTES
122 **
123 ** Basic rules:
124 **
125 **     * Both read and write access to the global write-op queue must be
126 **       protected by the async.queueMutex.
127 **
128 **     * The file handles from the underlying system are assumed not to
129 **       be thread safe.
130 **
131 **     * See the last two paragraphs under "The Writer Thread" for
132 **       an assumption to do with file-handle synchronization by the Os.
133 **
134 ** File system operations (invoked by SQLite thread):
135 **
136 **     xOpenXXX (three versions)
137 **     xDelete
138 **     xFileExists
139 **     xSyncDirectory
140 **
141 ** File handle operations (invoked by SQLite thread):
142 **
143 **         asyncWrite, asyncClose, asyncTruncate, asyncSync,
144 **         asyncSetFullSync, asyncOpenDirectory.
145 **
146 **     The operations above add an entry to the global write-op list. They
147 **     prepare the entry, acquire the async.queueMutex momentarily while
148 **     list pointers are  manipulated to insert the new entry, then release
149 **     the mutex and signal the writer thread to wake up in case it happens
150 **     to be asleep.
151 **
152 **
153 **         asyncRead, asyncFileSize.
154 **
155 **     Read operations. Both of these read from both the underlying file
156 **     first then adjust their result based on pending writes in the
157 **     write-op queue.   So async.queueMutex is held for the duration
158 **     of these operations to prevent other threads from changing the
159 **     queue in mid operation.
160 **
161 **
162 **         asyncLock, asyncUnlock, asyncLockState, asyncCheckReservedLock
163 **
164 **     These primitives implement in-process locking using a hash table
165 **     on the file name.  Files are locked correctly for connections coming
166 **     from the same process.  But other processes cannot see these locks
167 **     and will therefore not honor them.
168 **
169 **
170 **         asyncFileHandle.
171 **
172 **     The sqlite3OsFileHandle() function is currently only used when
173 **     debugging the pager module. Unless sqlite3OsClose() is called on the
174 **     file (shouldn't be possible for other reasons), the underlying
175 **     implementations are safe to call without grabbing any mutex. So we just
176 **     go ahead and call it no matter what any other threads are doing.
177 **
178 **
179 **         asyncSeek.
180 **
181 **     Calling this method just manipulates the AsyncFile.iOffset variable.
182 **     Since this variable is never accessed by writer thread, this
183 **     function does not require the mutex.  Actual calls to OsSeek() take
184 **     place just before OsWrite() or OsRead(), which are always protected by
185 **     the mutex.
186 **
187 ** The writer thread:
188 **
189 **     The async.writerMutex is used to make sure only there is only
190 **     a single writer thread running at a time.
191 **
192 **     Inside the writer thread is a loop that works like this:
193 **
194 **         WHILE (write-op list is not empty)
195 **             Do IO operation at head of write-op list
196 **             Remove entry from head of write-op list
197 **         END WHILE
198 **
199 **     The async.queueMutex is always held during the <write-op list is
200 **     not empty> test, and when the entry is removed from the head
201 **     of the write-op list. Sometimes it is held for the interim
202 **     period (while the IO is performed), and sometimes it is
203 **     relinquished. It is relinquished if (a) the IO op is an
204 **     ASYNC_CLOSE or (b) when the file handle was opened, two of
205 **     the underlying systems handles were opened on the same
206 **     file-system entry.
207 **
208 **     If condition (b) above is true, then one file-handle
209 **     (AsyncFile.pBaseRead) is used exclusively by sqlite threads to read the
210 **     file, the other (AsyncFile.pBaseWrite) by sqlite3_async_flush()
211 **     threads to perform write() operations. This means that read
212 **     operations are not blocked by asynchronous writes (although
213 **     asynchronous writes may still be blocked by reads).
214 **
215 **     This assumes that the OS keeps two handles open on the same file
216 **     properly in sync. That is, any read operation that starts after a
217 **     write operation on the same file system entry has completed returns
218 **     data consistent with the write. We also assume that if one thread
219 **     reads a file while another is writing it all bytes other than the
220 **     ones actually being written contain valid data.
221 **
222 **     If the above assumptions are not true, set the preprocessor symbol
223 **     SQLITE_ASYNC_TWO_FILEHANDLES to 0.
224 */
225 
226 #ifndef SQLITE_ASYNC_TWO_FILEHANDLES
227 /* #define SQLITE_ASYNC_TWO_FILEHANDLES 0 */
228 #define SQLITE_ASYNC_TWO_FILEHANDLES 1
229 #endif
230 
231 /*
232 ** State information is held in the static variable "async" defined
233 ** as follows:
234 */
235 static struct TestAsyncStaticData {
236   pthread_mutex_t queueMutex;  /* Mutex for access to write operation queue */
237   pthread_mutex_t writerMutex; /* Prevents multiple writer threads */
238   pthread_mutex_t lockMutex;   /* For access to aLock hash table */
239   pthread_cond_t queueSignal;  /* For waking up sleeping writer thread */
240   pthread_cond_t emptySignal;  /* Notify when the write queue is empty */
241   AsyncWrite *pQueueFirst;     /* Next write operation to be processed */
242   AsyncWrite *pQueueLast;      /* Last write operation on the list */
243   Hash aLock;                  /* Files locked */
244   volatile int ioDelay;             /* Extra delay between write operations */
245   volatile int writerHaltWhenIdle;  /* Writer thread halts when queue empty */
246   volatile int writerHaltNow;       /* Writer thread halts after next op */
247   int ioError;                 /* True if an IO error has occured */
248   int nFile;                   /* Number of open files (from sqlite pov) */
249 } async = {
250   PTHREAD_MUTEX_INITIALIZER,
251   PTHREAD_MUTEX_INITIALIZER,
252   PTHREAD_MUTEX_INITIALIZER,
253   PTHREAD_COND_INITIALIZER,
254   PTHREAD_COND_INITIALIZER,
255 };
256 
257 /* Possible values of AsyncWrite.op */
258 #define ASYNC_NOOP          0
259 #define ASYNC_WRITE         1
260 #define ASYNC_SYNC          2
261 #define ASYNC_TRUNCATE      3
262 #define ASYNC_CLOSE         4
263 #define ASYNC_OPENDIRECTORY 5
264 #define ASYNC_SETFULLSYNC   6
265 #define ASYNC_DELETE        7
266 #define ASYNC_OPENEXCLUSIVE 8
267 #define ASYNC_SYNCDIRECTORY 9
268 
269 /* Names of opcodes.  Used for debugging only.
270 ** Make sure these stay in sync with the macros above!
271 */
272 static const char *azOpcodeName[] = {
273   "NOOP", "WRITE", "SYNC", "TRUNCATE", "CLOSE",
274   "OPENDIR", "SETFULLSYNC", "DELETE", "OPENEX", "SYNCDIR",
275 };
276 
277 /*
278 ** Entries on the write-op queue are instances of the AsyncWrite
279 ** structure, defined here.
280 **
281 ** The interpretation of the iOffset and nByte variables varies depending
282 ** on the value of AsyncWrite.op:
283 **
284 ** ASYNC_WRITE:
285 **     iOffset -> Offset in file to write to.
286 **     nByte   -> Number of bytes of data to write (pointed to by zBuf).
287 **
288 ** ASYNC_SYNC:
289 **     iOffset -> Unused.
290 **     nByte   -> Value of "fullsync" flag to pass to sqlite3OsSync().
291 **
292 ** ASYNC_TRUNCATE:
293 **     iOffset -> Size to truncate file to.
294 **     nByte   -> Unused.
295 **
296 ** ASYNC_CLOSE:
297 **     iOffset -> Unused.
298 **     nByte   -> Unused.
299 **
300 ** ASYNC_OPENDIRECTORY:
301 **     iOffset -> Unused.
302 **     nByte   -> Number of bytes of zBuf points to (directory name).
303 **
304 ** ASYNC_SETFULLSYNC:
305 **     iOffset -> Unused.
306 **     nByte   -> New value for the full-sync flag.
307 **
308 **
309 ** ASYNC_DELETE:
310 **     iOffset -> Unused.
311 **     nByte   -> Number of bytes of zBuf points to (file name).
312 **
313 ** ASYNC_OPENEXCLUSIVE:
314 **     iOffset -> Value of "delflag".
315 **     nByte   -> Number of bytes of zBuf points to (file name).
316 **
317 **
318 ** For an ASYNC_WRITE operation, zBuf points to the data to write to the file.
319 ** This space is sqliteMalloc()d along with the AsyncWrite structure in a
320 ** single blob, so is deleted when sqliteFree() is called on the parent
321 ** structure.
322 */
323 struct AsyncWrite {
324   AsyncFile *pFile;   /* File to write data to or sync */
325   int op;             /* One of ASYNC_xxx etc. */
326   i64 iOffset;        /* See above */
327   int nByte;          /* See above */
328   char *zBuf;         /* Data to write to file (or NULL if op!=ASYNC_WRITE) */
329   AsyncWrite *pNext;  /* Next write operation (to any file) */
330 };
331 
332 /*
333 ** The AsyncFile structure is a subclass of OsFile used for asynchronous IO.
334 */
335 struct AsyncFile {
336   IoMethod *pMethod;   /* Must be first */
337   i64 iOffset;         /* Current seek() offset in file */
338   char *zName;         /* Underlying OS filename - used for debugging */
339   int nName;           /* Number of characters in zName */
340   OsFile *pBaseRead;   /* Read handle to the underlying Os file */
341   OsFile *pBaseWrite;  /* Write handle to the underlying Os file */
342 };
343 
344 /*
345 ** Add an entry to the end of the global write-op list. pWrite should point
346 ** to an AsyncWrite structure allocated using sqlite3OsMalloc().  The writer
347 ** thread will call sqlite3OsFree() to free the structure after the specified
348 ** operation has been completed.
349 **
350 ** Once an AsyncWrite structure has been added to the list, it becomes the
351 ** property of the writer thread and must not be read or modified by the
352 ** caller.
353 */
354 static void addAsyncWrite(AsyncWrite *pWrite){
355   /* We must hold the queue mutex in order to modify the queue pointers */
356   pthread_mutex_lock(&async.queueMutex);
357 
358   /* Add the record to the end of the write-op queue */
359   assert( !pWrite->pNext );
360   if( async.pQueueLast ){
361     assert( async.pQueueFirst );
362     async.pQueueLast->pNext = pWrite;
363   }else{
364     async.pQueueFirst = pWrite;
365   }
366   async.pQueueLast = pWrite;
367   ASYNC_TRACE(("PUSH %p (%s %s %d)\n", pWrite, azOpcodeName[pWrite->op],
368          pWrite->pFile ? pWrite->pFile->zName : "-", pWrite->iOffset));
369 
370   if( pWrite->op==ASYNC_CLOSE ){
371     async.nFile--;
372     if( async.nFile==0 ){
373       async.ioError = SQLITE_OK;
374     }
375   }
376 
377   /* Drop the queue mutex */
378   pthread_mutex_unlock(&async.queueMutex);
379 
380   /* The writer thread might have been idle because there was nothing
381   ** on the write-op queue for it to do.  So wake it up. */
382   pthread_cond_signal(&async.queueSignal);
383 }
384 
385 /*
386 ** Increment async.nFile in a thread-safe manner.
387 */
388 static void incrOpenFileCount(){
389   /* We must hold the queue mutex in order to modify async.nFile */
390   pthread_mutex_lock(&async.queueMutex);
391   if( async.nFile==0 ){
392     async.ioError = SQLITE_OK;
393   }
394   async.nFile++;
395   pthread_mutex_unlock(&async.queueMutex);
396 }
397 
398 /*
399 ** This is a utility function to allocate and populate a new AsyncWrite
400 ** structure and insert it (via addAsyncWrite() ) into the global list.
401 */
402 static int addNewAsyncWrite(
403   AsyncFile *pFile,
404   int op,
405   i64 iOffset,
406   int nByte,
407   const char *zByte
408 ){
409   AsyncWrite *p;
410   if( op!=ASYNC_CLOSE && async.ioError ){
411     return async.ioError;
412   }
413   p = sqlite3OsMalloc(sizeof(AsyncWrite) + (zByte?nByte:0));
414   if( !p ){
415     return SQLITE_NOMEM;
416   }
417   p->op = op;
418   p->iOffset = iOffset;
419   p->nByte = nByte;
420   p->pFile = pFile;
421   p->pNext = 0;
422   if( zByte ){
423     p->zBuf = (char *)&p[1];
424     memcpy(p->zBuf, zByte, nByte);
425   }else{
426     p->zBuf = 0;
427   }
428   addAsyncWrite(p);
429   return SQLITE_OK;
430 }
431 
432 /*
433 ** Close the file. This just adds an entry to the write-op list, the file is
434 ** not actually closed.
435 */
436 static int asyncClose(OsFile **pId){
437   return addNewAsyncWrite((AsyncFile *)*pId, ASYNC_CLOSE, 0, 0, 0);
438 }
439 
440 /*
441 ** Implementation of sqlite3OsWrite() for asynchronous files. Instead of
442 ** writing to the underlying file, this function adds an entry to the end of
443 ** the global AsyncWrite list. Either SQLITE_OK or SQLITE_NOMEM may be
444 ** returned.
445 */
446 static int asyncWrite(OsFile *id, const void *pBuf, int amt){
447   AsyncFile *pFile = (AsyncFile *)id;
448   int rc = addNewAsyncWrite(pFile, ASYNC_WRITE, pFile->iOffset, amt, pBuf);
449   pFile->iOffset += (i64)amt;
450   return rc;
451 }
452 
453 /*
454 ** Truncate the file to nByte bytes in length. This just adds an entry to
455 ** the write-op list, no IO actually takes place.
456 */
457 static int asyncTruncate(OsFile *id, i64 nByte){
458   return addNewAsyncWrite((AsyncFile *)id, ASYNC_TRUNCATE, nByte, 0, 0);
459 }
460 
461 /*
462 ** Open the directory identified by zName and associate it with the
463 ** specified file. This just adds an entry to the write-op list, the
464 ** directory is opened later by sqlite3_async_flush().
465 */
466 static int asyncOpenDirectory(OsFile *id, const char *zName){
467   AsyncFile *pFile = (AsyncFile *)id;
468   return addNewAsyncWrite(pFile, ASYNC_OPENDIRECTORY, 0, strlen(zName)+1,zName);
469 }
470 
471 /*
472 ** Sync the file. This just adds an entry to the write-op list, the
473 ** sync() is done later by sqlite3_async_flush().
474 */
475 static int asyncSync(OsFile *id, int fullsync){
476   return addNewAsyncWrite((AsyncFile *)id, ASYNC_SYNC, 0, fullsync, 0);
477 }
478 
479 /*
480 ** Set (or clear) the full-sync flag on the underlying file. This operation
481 ** is queued and performed later by sqlite3_async_flush().
482 */
483 static void asyncSetFullSync(OsFile *id, int value){
484   addNewAsyncWrite((AsyncFile *)id, ASYNC_SETFULLSYNC, 0, value, 0);
485 }
486 
487 /*
488 ** Read data from the file. First we read from the filesystem, then adjust
489 ** the contents of the buffer based on ASYNC_WRITE operations in the
490 ** write-op queue.
491 **
492 ** This method holds the mutex from start to finish.
493 */
494 static int asyncRead(OsFile *id, void *obuf, int amt){
495   int rc = SQLITE_OK;
496   i64 filesize;
497   int nRead;
498   AsyncFile *pFile = (AsyncFile *)id;
499   OsFile *pBase = pFile->pBaseRead;
500 
501   /* If an I/O error has previously occurred on this file, then all
502   ** subsequent operations fail.
503   */
504   if( async.ioError!=SQLITE_OK ){
505     return async.ioError;
506   }
507 
508   /* Grab the write queue mutex for the duration of the call */
509   pthread_mutex_lock(&async.queueMutex);
510 
511   if( pBase ){
512     rc = sqlite3OsFileSize(pBase, &filesize);
513     if( rc!=SQLITE_OK ){
514       goto asyncread_out;
515     }
516     rc = sqlite3OsSeek(pBase, pFile->iOffset);
517     if( rc!=SQLITE_OK ){
518       goto asyncread_out;
519     }
520     nRead = MIN(filesize - pFile->iOffset, amt);
521     if( nRead>0 ){
522       rc = sqlite3OsRead(pBase, obuf, nRead);
523       ASYNC_TRACE(("READ %s %d bytes at %d\n", pFile->zName, nRead, pFile->iOffset));
524     }
525   }
526 
527   if( rc==SQLITE_OK ){
528     AsyncWrite *p;
529     i64 iOffset = pFile->iOffset;           /* Current seek offset */
530 
531     for(p=async.pQueueFirst; p; p = p->pNext){
532       if( p->pFile==pFile && p->op==ASYNC_WRITE ){
533         int iBeginOut = (p->iOffset - iOffset);
534         int iBeginIn = -iBeginOut;
535         int nCopy;
536 
537         if( iBeginIn<0 ) iBeginIn = 0;
538         if( iBeginOut<0 ) iBeginOut = 0;
539         nCopy = MIN(p->nByte-iBeginIn, amt-iBeginOut);
540 
541         if( nCopy>0 ){
542           memcpy(&((char *)obuf)[iBeginOut], &p->zBuf[iBeginIn], nCopy);
543           ASYNC_TRACE(("OVERREAD %d bytes at %d\n", nCopy, iBeginOut+iOffset));
544         }
545       }
546     }
547 
548     pFile->iOffset += (i64)amt;
549   }
550 
551 asyncread_out:
552   pthread_mutex_unlock(&async.queueMutex);
553   return rc;
554 }
555 
556 /*
557 ** Seek to the specified offset. This just adjusts the AsyncFile.iOffset
558 ** variable - calling seek() on the underlying file is defered until the
559 ** next read() or write() operation.
560 */
561 static int asyncSeek(OsFile *id, i64 offset){
562   AsyncFile *pFile = (AsyncFile *)id;
563   pFile->iOffset = offset;
564   return SQLITE_OK;
565 }
566 
567 /*
568 ** Read the size of the file. First we read the size of the file system
569 ** entry, then adjust for any ASYNC_WRITE or ASYNC_TRUNCATE operations
570 ** currently in the write-op list.
571 **
572 ** This method holds the mutex from start to finish.
573 */
574 int asyncFileSize(OsFile *id, i64 *pSize){
575   int rc = SQLITE_OK;
576   i64 s = 0;
577   OsFile *pBase;
578 
579   pthread_mutex_lock(&async.queueMutex);
580 
581   /* Read the filesystem size from the base file. If pBaseRead is NULL, this
582   ** means the file hasn't been opened yet. In this case all relevant data
583   ** must be in the write-op queue anyway, so we can omit reading from the
584   ** file-system.
585   */
586   pBase = ((AsyncFile *)id)->pBaseRead;
587   if( pBase ){
588     rc = sqlite3OsFileSize(pBase, &s);
589   }
590 
591   if( rc==SQLITE_OK ){
592     AsyncWrite *p;
593     for(p=async.pQueueFirst; p; p = p->pNext){
594       if( p->pFile==(AsyncFile *)id ){
595         switch( p->op ){
596           case ASYNC_WRITE:
597             s = MAX(p->iOffset + (i64)(p->nByte), s);
598             break;
599           case ASYNC_TRUNCATE:
600             s = MIN(s, p->iOffset);
601             break;
602         }
603       }
604     }
605     *pSize = s;
606   }
607   pthread_mutex_unlock(&async.queueMutex);
608   return rc;
609 }
610 
611 /*
612 ** Return the operating system file handle. This is only used for debugging
613 ** at the moment anyway.
614 */
615 static int asyncFileHandle(OsFile *id){
616   return sqlite3OsFileHandle(((AsyncFile *)id)->pBaseRead);
617 }
618 
619 /*
620 ** No disk locking is performed.  We keep track of locks locally in
621 ** the async.aLock hash table.  Locking should appear to work the same
622 ** as with standard (unmodified) SQLite as long as all connections
623 ** come from this one process.  Connections from external processes
624 ** cannot see our internal hash table (obviously) and will thus not
625 ** honor our locks.
626 */
627 static int asyncLock(OsFile *id, int lockType){
628   AsyncFile *pFile = (AsyncFile*)id;
629   ASYNC_TRACE(("LOCK %d (%s)\n", lockType, pFile->zName));
630   pthread_mutex_lock(&async.lockMutex);
631   sqlite3HashInsert(&async.aLock, pFile->zName, pFile->nName, (void*)lockType);
632   pthread_mutex_unlock(&async.lockMutex);
633   return SQLITE_OK;
634 }
635 static int asyncUnlock(OsFile *id, int lockType){
636   return asyncLock(id, lockType);
637 }
638 
639 /*
640 ** This function is called when the pager layer first opens a database file
641 ** and is checking for a hot-journal.
642 */
643 static int asyncCheckReservedLock(OsFile *id){
644   AsyncFile *pFile = (AsyncFile*)id;
645   int rc;
646   pthread_mutex_lock(&async.lockMutex);
647   rc = (int)sqlite3HashFind(&async.aLock, pFile->zName, pFile->nName);
648   pthread_mutex_unlock(&async.lockMutex);
649   ASYNC_TRACE(("CHECK-LOCK %d (%s)\n", rc, pFile->zName));
650   return rc>SHARED_LOCK;
651 }
652 
653 static int asyncSectorSize(OsFile *id){
654   /* TODO: This is tricky to implement, as this backend might not have
655   ** an open file handle at this point.
656   */
657   return 512;
658 }
659 
660 /*
661 ** This is broken. But sqlite3OsLockState() is only used for testing anyway.
662 */
663 static int asyncLockState(OsFile *id){
664   return SQLITE_OK;
665 }
666 
667 /*
668 ** The following variables hold pointers to the original versions of
669 ** OS-layer interface routines that are overloaded in order to create
670 ** the asynchronous I/O backend.
671 */
672 static int (*xOrigOpenReadWrite)(const char*, OsFile**, int*) = 0;
673 static int (*xOrigOpenExclusive)(const char*, OsFile**, int) = 0;
674 static int (*xOrigOpenReadOnly)(const char*, OsFile**) = 0;
675 static int (*xOrigDelete)(const char*) = 0;
676 static int (*xOrigFileExists)(const char*) = 0;
677 static int (*xOrigSyncDirectory)(const char*) = 0;
678 
679 /*
680 ** This routine does most of the work of opening a file and building
681 ** the OsFile structure.
682 */
683 static int asyncOpenFile(
684   const char *zName,     /* The name of the file to be opened */
685   OsFile **pFile,        /* Put the OsFile structure here */
686   OsFile *pBaseRead,     /* The real OsFile from the real I/O routine */
687   int openForWriting     /* Open a second file handle for writing if true */
688 ){
689   int rc, i, n;
690   AsyncFile *p;
691   OsFile *pBaseWrite = 0;
692 
693   static IoMethod iomethod = {
694     asyncClose,
695     asyncOpenDirectory,
696     asyncRead,
697     asyncWrite,
698     asyncSeek,
699     asyncTruncate,
700     asyncSync,
701     asyncSetFullSync,
702     asyncFileHandle,
703     asyncFileSize,
704     asyncLock,
705     asyncUnlock,
706     asyncLockState,
707     asyncCheckReservedLock,
708     asyncSectorSize,
709   };
710 
711   if( openForWriting && SQLITE_ASYNC_TWO_FILEHANDLES ){
712     int dummy;
713     rc = xOrigOpenReadWrite(zName, &pBaseWrite, &dummy);
714     if( rc!=SQLITE_OK ){
715       goto error_out;
716     }
717   }
718 
719   n = strlen(zName);
720   for(i=n-1; i>=0 && zName[i]!='/'; i--){}
721   p = (AsyncFile *)sqlite3OsMalloc(sizeof(AsyncFile) + n - i);
722   if( !p ){
723     rc = SQLITE_NOMEM;
724     goto error_out;
725   }
726   memset(p, 0, sizeof(AsyncFile));
727   p->zName = (char*)&p[1];
728   strcpy(p->zName, &zName[i+1]);
729   p->nName = n - i;
730   p->pMethod = &iomethod;
731   p->pBaseRead = pBaseRead;
732   p->pBaseWrite = pBaseWrite;
733 
734   *pFile = (OsFile *)p;
735   return SQLITE_OK;
736 
737 error_out:
738   assert(!p);
739   sqlite3OsClose(&pBaseRead);
740   sqlite3OsClose(&pBaseWrite);
741   *pFile = 0;
742   return rc;
743 }
744 
745 /*
746 ** The async-IO backends implementation of the three functions used to open
747 ** a file (xOpenExclusive, xOpenReadWrite and xOpenReadOnly). Most of the
748 ** work is done in function asyncOpenFile() - see above.
749 */
750 static int asyncOpenExclusive(const char *z, OsFile **ppFile, int delFlag){
751   int rc = asyncOpenFile(z, ppFile, 0, 0);
752   if( rc==SQLITE_OK ){
753     AsyncFile *pFile = (AsyncFile *)(*ppFile);
754     int nByte = strlen(z)+1;
755     i64 i = (i64)(delFlag);
756     rc = addNewAsyncWrite(pFile, ASYNC_OPENEXCLUSIVE, i, nByte, z);
757     if( rc!=SQLITE_OK ){
758       sqlite3OsFree(pFile);
759       *ppFile = 0;
760     }
761   }
762   if( rc==SQLITE_OK ){
763     incrOpenFileCount();
764   }
765   return rc;
766 }
767 static int asyncOpenReadOnly(const char *z, OsFile **ppFile){
768   OsFile *pBase = 0;
769   int rc = xOrigOpenReadOnly(z, &pBase);
770   if( rc==SQLITE_OK ){
771     rc = asyncOpenFile(z, ppFile, pBase, 0);
772   }
773   if( rc==SQLITE_OK ){
774     incrOpenFileCount();
775   }
776   return rc;
777 }
778 static int asyncOpenReadWrite(const char *z, OsFile **ppFile, int *pReadOnly){
779   OsFile *pBase = 0;
780   int rc = xOrigOpenReadWrite(z, &pBase, pReadOnly);
781   if( rc==SQLITE_OK ){
782     rc = asyncOpenFile(z, ppFile, pBase, (*pReadOnly ? 0 : 1));
783   }
784   if( rc==SQLITE_OK ){
785     incrOpenFileCount();
786   }
787   return rc;
788 }
789 
790 /*
791 ** Implementation of sqlite3OsDelete. Add an entry to the end of the
792 ** write-op queue to perform the delete.
793 */
794 static int asyncDelete(const char *z){
795   return addNewAsyncWrite(0, ASYNC_DELETE, 0, strlen(z)+1, z);
796 }
797 
798 /*
799 ** Implementation of sqlite3OsSyncDirectory. Add an entry to the end of the
800 ** write-op queue to perform the directory sync.
801 */
802 static int asyncSyncDirectory(const char *z){
803   return addNewAsyncWrite(0, ASYNC_SYNCDIRECTORY, 0, strlen(z)+1, z);
804 }
805 
806 /*
807 ** Implementation of sqlite3OsFileExists. Return true if file 'z' exists
808 ** in the file system.
809 **
810 ** This method holds the mutex from start to finish.
811 */
812 static int asyncFileExists(const char *z){
813   int ret;
814   AsyncWrite *p;
815 
816   pthread_mutex_lock(&async.queueMutex);
817 
818   /* See if the real file system contains the specified file.  */
819   ret = xOrigFileExists(z);
820 
821   for(p=async.pQueueFirst; p; p = p->pNext){
822     if( p->op==ASYNC_DELETE && 0==strcmp(p->zBuf, z) ){
823       ret = 0;
824     }else if( p->op==ASYNC_OPENEXCLUSIVE && 0==strcmp(p->zBuf, z) ){
825       ret = 1;
826     }
827   }
828 
829   ASYNC_TRACE(("EXISTS: %s = %d\n", z, ret));
830   pthread_mutex_unlock(&async.queueMutex);
831   return ret;
832 }
833 
834 /*
835 ** Call this routine to enable or disable the
836 ** asynchronous IO features implemented in this file.
837 **
838 ** This routine is not even remotely threadsafe.  Do not call
839 ** this routine while any SQLite database connections are open.
840 */
841 static void asyncEnable(int enable){
842   if( enable && xOrigOpenReadWrite==0 ){
843     assert(sqlite3Os.xOpenReadWrite);
844     sqlite3HashInit(&async.aLock, SQLITE_HASH_BINARY, 1);
845     xOrigOpenReadWrite = sqlite3Os.xOpenReadWrite;
846     xOrigOpenReadOnly = sqlite3Os.xOpenReadOnly;
847     xOrigOpenExclusive = sqlite3Os.xOpenExclusive;
848     xOrigDelete = sqlite3Os.xDelete;
849     xOrigFileExists = sqlite3Os.xFileExists;
850     xOrigSyncDirectory = sqlite3Os.xSyncDirectory;
851 
852     sqlite3Os.xOpenReadWrite = asyncOpenReadWrite;
853     sqlite3Os.xOpenReadOnly = asyncOpenReadOnly;
854     sqlite3Os.xOpenExclusive = asyncOpenExclusive;
855     sqlite3Os.xDelete = asyncDelete;
856     sqlite3Os.xFileExists = asyncFileExists;
857     sqlite3Os.xSyncDirectory = asyncSyncDirectory;
858     assert(sqlite3Os.xOpenReadWrite);
859   }
860   if( !enable && xOrigOpenReadWrite!=0 ){
861     assert(sqlite3Os.xOpenReadWrite);
862     sqlite3HashClear(&async.aLock);
863     sqlite3Os.xOpenReadWrite = xOrigOpenReadWrite;
864     sqlite3Os.xOpenReadOnly = xOrigOpenReadOnly;
865     sqlite3Os.xOpenExclusive = xOrigOpenExclusive;
866     sqlite3Os.xDelete = xOrigDelete;
867     sqlite3Os.xFileExists = xOrigFileExists;
868     sqlite3Os.xSyncDirectory = xOrigSyncDirectory;
869 
870     xOrigOpenReadWrite = 0;
871     xOrigOpenReadOnly = 0;
872     xOrigOpenExclusive = 0;
873     xOrigDelete = 0;
874     xOrigFileExists = 0;
875     xOrigSyncDirectory = 0;
876     assert(sqlite3Os.xOpenReadWrite);
877   }
878 }
879 
880 /*
881 ** This procedure runs in a separate thread, reading messages off of the
882 ** write queue and processing them one by one.
883 **
884 ** If async.writerHaltNow is true, then this procedure exits
885 ** after processing a single message.
886 **
887 ** If async.writerHaltWhenIdle is true, then this procedure exits when
888 ** the write queue is empty.
889 **
890 ** If both of the above variables are false, this procedure runs
891 ** indefinately, waiting for operations to be added to the write queue
892 ** and processing them in the order in which they arrive.
893 **
894 ** An artifical delay of async.ioDelay milliseconds is inserted before
895 ** each write operation in order to simulate the effect of a slow disk.
896 **
897 ** Only one instance of this procedure may be running at a time.
898 */
899 static void *asyncWriterThread(void *NotUsed){
900   AsyncWrite *p = 0;
901   int rc = SQLITE_OK;
902   int holdingMutex = 0;
903 
904   if( pthread_mutex_trylock(&async.writerMutex) ){
905     return 0;
906   }
907   while( async.writerHaltNow==0 ){
908     OsFile *pBase = 0;
909 
910     if( !holdingMutex ){
911       pthread_mutex_lock(&async.queueMutex);
912     }
913     while( (p = async.pQueueFirst)==0 ){
914       pthread_cond_broadcast(&async.emptySignal);
915       if( async.writerHaltWhenIdle ){
916         pthread_mutex_unlock(&async.queueMutex);
917         break;
918       }else{
919         ASYNC_TRACE(("IDLE\n"));
920         pthread_cond_wait(&async.queueSignal, &async.queueMutex);
921         ASYNC_TRACE(("WAKEUP\n"));
922       }
923     }
924     if( p==0 ) break;
925     holdingMutex = 1;
926 
927     /* Right now this thread is holding the mutex on the write-op queue.
928     ** Variable 'p' points to the first entry in the write-op queue. In
929     ** the general case, we hold on to the mutex for the entire body of
930     ** the loop.
931     **
932     ** However in the cases enumerated below, we relinquish the mutex,
933     ** perform the IO, and then re-request the mutex before removing 'p' from
934     ** the head of the write-op queue. The idea is to increase concurrency with
935     ** sqlite threads.
936     **
937     **     * An ASYNC_CLOSE operation.
938     **     * An ASYNC_OPENEXCLUSIVE operation. For this one, we relinquish
939     **       the mutex, call the underlying xOpenExclusive() function, then
940     **       re-aquire the mutex before seting the AsyncFile.pBaseRead
941     **       variable.
942     **     * ASYNC_SYNC and ASYNC_WRITE operations, if
943     **       SQLITE_ASYNC_TWO_FILEHANDLES was set at compile time and two
944     **       file-handles are open for the particular file being "synced".
945     */
946     if( async.ioError!=SQLITE_OK && p->op!=ASYNC_CLOSE ){
947       p->op = ASYNC_NOOP;
948     }
949     if( p->pFile ){
950       pBase = p->pFile->pBaseWrite;
951       if(
952         p->op==ASYNC_CLOSE ||
953         p->op==ASYNC_OPENEXCLUSIVE ||
954         (pBase && (p->op==ASYNC_SYNC || p->op==ASYNC_WRITE) )
955       ){
956         pthread_mutex_unlock(&async.queueMutex);
957         holdingMutex = 0;
958       }
959       if( !pBase ){
960         pBase = p->pFile->pBaseRead;
961       }
962     }
963 
964     switch( p->op ){
965       case ASYNC_NOOP:
966         break;
967 
968       case ASYNC_WRITE:
969         assert( pBase );
970         ASYNC_TRACE(("WRITE %s %d bytes at %d\n",
971                 p->pFile->zName, p->nByte, p->iOffset));
972         rc = sqlite3OsSeek(pBase, p->iOffset);
973         if( rc==SQLITE_OK ){
974           rc = sqlite3OsWrite(pBase, (const void *)(p->zBuf), p->nByte);
975         }
976         break;
977 
978       case ASYNC_SYNC:
979         assert( pBase );
980         ASYNC_TRACE(("SYNC %s\n", p->pFile->zName));
981         rc = sqlite3OsSync(pBase, p->nByte);
982         break;
983 
984       case ASYNC_TRUNCATE:
985         assert( pBase );
986         ASYNC_TRACE(("TRUNCATE %s to %d bytes\n", p->pFile->zName, p->iOffset));
987         rc = sqlite3OsTruncate(pBase, p->iOffset);
988         break;
989 
990       case ASYNC_CLOSE:
991         ASYNC_TRACE(("CLOSE %s\n", p->pFile->zName));
992         sqlite3OsClose(&p->pFile->pBaseWrite);
993         sqlite3OsClose(&p->pFile->pBaseRead);
994         sqlite3OsFree(p->pFile);
995         break;
996 
997       case ASYNC_OPENDIRECTORY:
998         assert( pBase );
999         ASYNC_TRACE(("OPENDIR %s\n", p->zBuf));
1000         sqlite3OsOpenDirectory(pBase, p->zBuf);
1001         break;
1002 
1003       case ASYNC_SETFULLSYNC:
1004         assert( pBase );
1005         ASYNC_TRACE(("SETFULLSYNC %s %d\n", p->pFile->zName, p->nByte));
1006         sqlite3OsSetFullSync(pBase, p->nByte);
1007         break;
1008 
1009       case ASYNC_DELETE:
1010         ASYNC_TRACE(("DELETE %s\n", p->zBuf));
1011         rc = xOrigDelete(p->zBuf);
1012         break;
1013 
1014       case ASYNC_SYNCDIRECTORY:
1015         ASYNC_TRACE(("SYNCDIR %s\n", p->zBuf));
1016         rc = xOrigSyncDirectory(p->zBuf);
1017         break;
1018 
1019       case ASYNC_OPENEXCLUSIVE: {
1020         AsyncFile *pFile = p->pFile;
1021         int delFlag = ((p->iOffset)?1:0);
1022         OsFile *pBase = 0;
1023         ASYNC_TRACE(("OPEN %s delFlag=%d\n", p->zBuf, delFlag));
1024         assert(pFile->pBaseRead==0 && pFile->pBaseWrite==0);
1025         rc = xOrigOpenExclusive(p->zBuf, &pBase, delFlag);
1026         assert( holdingMutex==0 );
1027         pthread_mutex_lock(&async.queueMutex);
1028         holdingMutex = 1;
1029         if( rc==SQLITE_OK ){
1030           pFile->pBaseRead = pBase;
1031         }
1032         break;
1033       }
1034 
1035       default: assert(!"Illegal value for AsyncWrite.op");
1036     }
1037 
1038     /* If we didn't hang on to the mutex during the IO op, obtain it now
1039     ** so that the AsyncWrite structure can be safely removed from the
1040     ** global write-op queue.
1041     */
1042     if( !holdingMutex ){
1043       pthread_mutex_lock(&async.queueMutex);
1044       holdingMutex = 1;
1045     }
1046     /* ASYNC_TRACE(("UNLINK %p\n", p)); */
1047     if( p==async.pQueueLast ){
1048       async.pQueueLast = 0;
1049     }
1050     async.pQueueFirst = p->pNext;
1051     sqlite3OsFree(p);
1052     assert( holdingMutex );
1053 
1054     /* An IO error has occured. We cannot report the error back to the
1055     ** connection that requested the I/O since the error happened
1056     ** asynchronously.  The connection has already moved on.  There
1057     ** really is nobody to report the error to.
1058     **
1059     ** The file for which the error occured may have been a database or
1060     ** journal file. Regardless, none of the currently queued operations
1061     ** associated with the same database should now be performed. Nor should
1062     ** any subsequently requested IO on either a database or journal file
1063     ** handle for the same database be accepted until the main database
1064     ** file handle has been closed and reopened.
1065     **
1066     ** Furthermore, no further IO should be queued or performed on any file
1067     ** handle associated with a database that may have been part of a
1068     ** multi-file transaction that included the database associated with
1069     ** the IO error (i.e. a database ATTACHed to the same handle at some
1070     ** point in time).
1071     */
1072     if( rc!=SQLITE_OK ){
1073       async.ioError = rc;
1074     }
1075 
1076     /* Drop the queue mutex before continuing to the next write operation
1077     ** in order to give other threads a chance to work with the write queue.
1078     */
1079     if( !async.pQueueFirst || !async.ioError ){
1080       sqlite3ApiExit(0, 0);
1081       pthread_mutex_unlock(&async.queueMutex);
1082       holdingMutex = 0;
1083       if( async.ioDelay>0 ){
1084         sqlite3OsSleep(async.ioDelay);
1085       }else{
1086         sched_yield();
1087       }
1088     }
1089   }
1090 
1091   pthread_mutex_unlock(&async.writerMutex);
1092   return 0;
1093 }
1094 
1095 /**************************************************************************
1096 ** The remaining code defines a Tcl interface for testing the asynchronous
1097 ** IO implementation in this file.
1098 **
1099 ** To adapt the code to a non-TCL environment, delete or comment out
1100 ** the code that follows.
1101 */
1102 
1103 /*
1104 ** sqlite3async_enable ?YES/NO?
1105 **
1106 ** Enable or disable the asynchronous I/O backend.  This command is
1107 ** not thread-safe.  Do not call it while any database connections
1108 ** are open.
1109 */
1110 static int testAsyncEnable(
1111   void * clientData,
1112   Tcl_Interp *interp,
1113   int objc,
1114   Tcl_Obj *CONST objv[]
1115 ){
1116   if( objc!=1 && objc!=2 ){
1117     Tcl_WrongNumArgs(interp, 1, objv, "?YES/NO?");
1118     return TCL_ERROR;
1119   }
1120   if( objc==1 ){
1121     Tcl_SetObjResult(interp, Tcl_NewBooleanObj(xOrigOpenReadWrite!=0));
1122   }else{
1123     int en;
1124     if( Tcl_GetBooleanFromObj(interp, objv[1], &en) ) return TCL_ERROR;
1125     asyncEnable(en);
1126   }
1127   return TCL_OK;
1128 }
1129 
1130 /*
1131 ** sqlite3async_halt  "now"|"idle"|"never"
1132 **
1133 ** Set the conditions at which the writer thread will halt.
1134 */
1135 static int testAsyncHalt(
1136   void * clientData,
1137   Tcl_Interp *interp,
1138   int objc,
1139   Tcl_Obj *CONST objv[]
1140 ){
1141   const char *zCond;
1142   if( objc!=2 ){
1143     Tcl_WrongNumArgs(interp, 1, objv, "\"now\"|\"idle\"|\"never\"");
1144     return TCL_ERROR;
1145   }
1146   zCond = Tcl_GetString(objv[1]);
1147   if( strcmp(zCond, "now")==0 ){
1148     async.writerHaltNow = 1;
1149     pthread_cond_broadcast(&async.queueSignal);
1150   }else if( strcmp(zCond, "idle")==0 ){
1151     async.writerHaltWhenIdle = 1;
1152     async.writerHaltNow = 0;
1153     pthread_cond_broadcast(&async.queueSignal);
1154   }else if( strcmp(zCond, "never")==0 ){
1155     async.writerHaltWhenIdle = 0;
1156     async.writerHaltNow = 0;
1157   }else{
1158     Tcl_AppendResult(interp,
1159       "should be one of: \"now\", \"idle\", or \"never\"", (char*)0);
1160     return TCL_ERROR;
1161   }
1162   return TCL_OK;
1163 }
1164 
1165 /*
1166 ** sqlite3async_delay ?MS?
1167 **
1168 ** Query or set the number of milliseconds of delay in the writer
1169 ** thread after each write operation.  The default is 0.  By increasing
1170 ** the memory delay we can simulate the effect of slow disk I/O.
1171 */
1172 static int testAsyncDelay(
1173   void * clientData,
1174   Tcl_Interp *interp,
1175   int objc,
1176   Tcl_Obj *CONST objv[]
1177 ){
1178   if( objc!=1 && objc!=2 ){
1179     Tcl_WrongNumArgs(interp, 1, objv, "?MS?");
1180     return TCL_ERROR;
1181   }
1182   if( objc==1 ){
1183     Tcl_SetObjResult(interp, Tcl_NewIntObj(async.ioDelay));
1184   }else{
1185     int ioDelay;
1186     if( Tcl_GetIntFromObj(interp, objv[1], &ioDelay) ) return TCL_ERROR;
1187     async.ioDelay = ioDelay;
1188   }
1189   return TCL_OK;
1190 }
1191 
1192 /*
1193 ** sqlite3async_start
1194 **
1195 ** Start a new writer thread.
1196 */
1197 static int testAsyncStart(
1198   void * clientData,
1199   Tcl_Interp *interp,
1200   int objc,
1201   Tcl_Obj *CONST objv[]
1202 ){
1203   pthread_t x;
1204   int rc;
1205   rc = pthread_create(&x, 0, asyncWriterThread, 0);
1206   if( rc ){
1207     Tcl_AppendResult(interp, "failed to create the thread", 0);
1208     return TCL_ERROR;
1209   }
1210   pthread_detach(x);
1211   return TCL_OK;
1212 }
1213 
1214 /*
1215 ** sqlite3async_wait
1216 **
1217 ** Wait for the current writer thread to terminate.
1218 **
1219 ** If the current writer thread is set to run forever then this
1220 ** command would block forever.  To prevent that, an error is returned.
1221 */
1222 static int testAsyncWait(
1223   void * clientData,
1224   Tcl_Interp *interp,
1225   int objc,
1226   Tcl_Obj *CONST objv[]
1227 ){
1228   int cnt = 10;
1229   if( async.writerHaltNow==0 && async.writerHaltWhenIdle==0 ){
1230     Tcl_AppendResult(interp, "would block forever", (char*)0);
1231     return TCL_ERROR;
1232   }
1233 
1234   while( cnt-- && !pthread_mutex_trylock(&async.writerMutex) ){
1235     pthread_mutex_unlock(&async.writerMutex);
1236     sched_yield();
1237   }
1238   if( cnt>=0 ){
1239     ASYNC_TRACE(("WAIT\n"));
1240     pthread_mutex_lock(&async.queueMutex);
1241     pthread_cond_broadcast(&async.queueSignal);
1242     pthread_mutex_unlock(&async.queueMutex);
1243     pthread_mutex_lock(&async.writerMutex);
1244     pthread_mutex_unlock(&async.writerMutex);
1245   }else{
1246     ASYNC_TRACE(("NO-WAIT\n"));
1247   }
1248   return TCL_OK;
1249 }
1250 
1251 
1252 #endif  /* OS_UNIX and THREADSAFE and defined(SQLITE_ENABLE_REDEF_IO) */
1253 
1254 /*
1255 ** This routine registers the custom TCL commands defined in this
1256 ** module.  This should be the only procedure visible from outside
1257 ** of this module.
1258 */
1259 int Sqlitetestasync_Init(Tcl_Interp *interp){
1260 #if OS_UNIX && THREADSAFE && defined(SQLITE_ENABLE_REDEF_IO)
1261   Tcl_CreateObjCommand(interp,"sqlite3async_enable",testAsyncEnable,0,0);
1262   Tcl_CreateObjCommand(interp,"sqlite3async_halt",testAsyncHalt,0,0);
1263   Tcl_CreateObjCommand(interp,"sqlite3async_delay",testAsyncDelay,0,0);
1264   Tcl_CreateObjCommand(interp,"sqlite3async_start",testAsyncStart,0,0);
1265   Tcl_CreateObjCommand(interp,"sqlite3async_wait",testAsyncWait,0,0);
1266   Tcl_LinkVar(interp, "sqlite3async_trace",
1267       (char*)&sqlite3async_trace, TCL_LINK_INT);
1268 #endif  /* OS_UNIX and THREADSAFE and defined(SQLITE_ENABLE_REDEF_IO) */
1269   return TCL_OK;
1270 }
1271