diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/test_async.c | 73 |
1 files changed, 61 insertions, 12 deletions
diff --git a/src/test_async.c b/src/test_async.c index de09edcda..4b7a27636 100644 --- a/src/test_async.c +++ b/src/test_async.c @@ -42,6 +42,11 @@ ** written directly to disk, but is placed in the "write-queue" to be ** handled by the background thread. ** +** When files opened with the asynchronous vfs are read from +** (using sqlite3OsRead()), the data is read from the file on +** disk and the write-queue, so that from the point of view of +** the vfs reader the OsWrite() appears to have already completed. +** ** The special vfs is registered (and unregistered) by calls to ** function asyncEnable() (see below). ** @@ -56,15 +61,48 @@ ** run out of memory. Users of this technique may want to keep track of ** the quantity of pending writes and stop accepting new write requests ** when the buffer gets to be too big. -*/ - -/* -** If this symbol is defined, then file-system locks are obtained as -** required. This slows things down, but allows multiple processes -** to access the database concurrently. If this symbol is not defined, -** then connections from within a single process will respect each -** others database locks, but external connections will not - leading -** to database corruption. +** +** LOCKING + CONCURRENCY +** +** Multiple connections from within a single process that use this +** implementation of asynchronous IO may access a single database +** file concurrently. From the point of view of the user, if all +** connections are from within a single process, there is no difference +** between the concurrency offered by "normal" SQLite and SQLite +** using the asynchronous backend. +** +** If connections from within multiple database files may access the +** database file, the ENABLE_FILE_LOCKING symbol (see below) must be +** defined. If it is not defined, then no locks are established on +** the database file. In this case, if multiple processes access +** the database file, corruption will quickly result. +** +** If ENABLE_FILE_LOCKING is defined (the default), then connections +** from within multiple processes may access a single database file +** without risking corruption. However concurrency is reduced as +** follows: +** +** * When a connection using asynchronous IO begins a database +** transaction, the database is locked immediately. However the +** lock is not released until after all relevant operations +** in the write-queue have been flushed to disk. This means +** (for example) that the database may remain locked for some +** time after a "COMMIT" or "ROLLBACK" is issued. +** +** * If an application using asynchronous IO executes transactions +** in quick succession, other database users may be effectively +** locked out of the database. This is because when a BEGIN +** is executed, a database lock is established immediately. But +** when the corresponding COMMIT or ROLLBACK occurs, the lock +** is not released until the relevant part of the write-queue +** has been flushed through. As a result, if a COMMIT is followed +** by a BEGIN before the write-queue is flushed through, the database +** is never unlocked,preventing other processes from accessing +** the database. +** +** Defining ENABLE_FILE_LOCKING when using an NFS or other remote +** file-system may slow things down, as synchronous round-trips to the +** server may be required to establish database file locks. */ #define ENABLE_FILE_LOCKING @@ -77,7 +115,6 @@ */ #if OS_UNIX && SQLITE_THREADSAFE - /* ** This demo uses pthreads. If you do not have a pthreads implementation ** for your operating system, you will need to recode the threading @@ -128,12 +165,24 @@ static void asyncTrace(const char *zFormat, ...){ ** * See the last two paragraphs under "The Writer Thread" for ** an assumption to do with file-handle synchronization by the Os. ** +** Deadlock prevention: +** +** There are three mutex used by the system: the "writer" mutex, +** the "queue" mutex and the "lock" mutex. Rules are: +** +** * It is illegal to block on the writer mutex when any other mutex +** are held, and +** +** * It is illegal to block on the queue mutex when the lock mutex +** is held. +** +** i.e. mutex's must be grabbed in the order "writer", "queue", "lock". +** ** File system operations (invoked by SQLite thread): ** -** xOpenXXX (three versions) +** xOpen ** xDelete ** xFileExists -** xSyncDirectory ** ** File handle operations (invoked by SQLite thread): ** |