]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Added the 34to35.html document describing the changes between 3.4.2 and
authordrh <drh@noemail.net>
Mon, 27 Aug 2007 21:10:36 +0000 (21:10 +0000)
committerdrh <drh@noemail.net>
Mon, 27 Aug 2007 21:10:36 +0000 (21:10 +0000)
3.5.0.  Minor interface cleanups. (CVS 4302)

FossilOrigin-Name: 0791f917bb18d7305b805b9cbcb308bdd7b3a1f5

main.mk
manifest
manifest.uuid
src/os_unix.c
src/os_win.c
src/sqlite.h.in
src/test_async.c
www/34to35.tcl [new file with mode: 0644]

diff --git a/main.mk b/main.mk
index f0bf6ef49e631fe504935a76940261c3a2803e2b..5ff4fb2f76c0f4b72a674e34b82d2e226f8735cf 100644 (file)
--- a/main.mk
+++ b/main.mk
@@ -707,6 +707,9 @@ version3.html:      $(TOP)/www/version3.tcl
 whentouse.html:        $(TOP)/www/whentouse.tcl
        tclsh $(TOP)/www/whentouse.tcl >whentouse.html
 
+34to35.html:   $(TOP)/www/34to35.tcl
+       tclsh $(TOP)/www/34to35.tcl >34to35.html
+
 
 # Files to be published on the website.
 #
@@ -750,7 +753,8 @@ DOC = \
   tclsqlite.html \
   vdbe.html \
   version3.html \
-  whentouse.html
+  whentouse.html \
+  34to35.html
 
 doc:   common.tcl $(DOC)
        mkdir -p doc
index 90c16bc3985feadaa038034bcd508b47af510f63..97f8b9459fd768ec8a458d6864c50d3b475585ff 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Modify\ssqlite3_release_memory()\sto\suse\sa\sglobal\sLRU\slist\sof\spages.\sUntested.\s(CVS\s4301)
-D 2007-08-27T17:27:49
+C Added\sthe\s34to35.html\sdocument\sdescribing\sthe\schanges\sbetween\s3.4.2\sand\n3.5.0.\s\sMinor\sinterface\scleanups.\s(CVS\s4302)
+D 2007-08-27T21:10:36
 F Makefile.in 938f2769921fa1b30c633548f153804021eb1512
 F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -63,7 +63,7 @@ F ext/icu/README.txt 3b130aa66e7a681136f6add198b076a2f90d1e33
 F ext/icu/icu.c 61a345d8126686aa3487aa8d2d0f68abd655f7a4
 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
 F ltmain.sh 56abb507100ed2d4261f6dd1653dec3cf4066387
-F main.mk 9e796bb4e04ca16d3d1506e6496a7468410dd441
+F main.mk 238b00009433760c469ceb94f37f49e76dceae45
 F mkdll.sh 37fa8a7412e51b5ab2bc6d4276135f022a0feffb
 F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
 F mkextw.sh 1a866b53637dab137191341cc875575a5ca110fb
@@ -111,9 +111,9 @@ F src/os_os2.c 8769301bff502de642ad2634cedcb77d967ce199
 F src/os_os2.h c3f7d0af7e3453d1d7aa81b06c0a56f5a226530b
 F src/os_test.c 49833426101f99aee4bb5f6a44b7c4b2029fda1c
 F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3
-F src/os_unix.c 27b1fad58587bc949013a5a4df9fc20fce395648
+F src/os_unix.c 7a340c712efa1bde95b6e23b7f279d9fb6e7dcf2
 F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
-F src/os_win.c 4f840e97624dbde9cae3d020ce072a4f1d2a11b1
+F src/os_win.c 3ffd3aacff4cb69848284e29dcec0feff23b0752
 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
 F src/pager.c cfa6dc38b797206549491de3ec7f0aea50611dda
 F src/pager.h 53087c6fb9db01aed17c7fd044662a27507e89b8
@@ -125,7 +125,7 @@ F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
 F src/select.c 98c367bce3f38c5adfcc97de9ab5c79b0e5dc2b2
 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/shell.c ac29402b538515fa4697282387be9c1205e6e9eb
-F src/sqlite.h.in 2d45cd3fc1b6677d06c8e547bbe1b9a040a7f677
+F src/sqlite.h.in 4cf42ce749e4bdf13b9bb4959e91439c3ce8a054
 F src/sqlite3ext.h 9a26028378c288af500d8b94ed079666fed5806b
 F src/sqliteInt.h 13c908f5f156a192fcd247f993ac513bfaf81f53
 F src/sqliteLimit.h 1bcbbdfa856f8b71b561abb31edb864b0eca1d12
@@ -140,7 +140,7 @@ F src/test6.c a6223d9d938aba83f20611a2c01680d8043cd2f7
 F src/test7.c a9d509d0e9ad214b4772696f49f6e61be26213d1
 F src/test8.c a91b8d28341bbd168f5ba1ecad2be1008ddf15d1
 F src/test9.c b46c8fe02ac7cca1a7316436d8d38d50c66f4b2f
-F src/test_async.c 12ff3db0e052f561596d4dbdd29272f28b25060d
+F src/test_async.c f222bd196b55a2e73b1427400d5aa97841787167
 F src/test_autoext.c 855157d97aa28cf84233847548bfacda21807436
 F src/test_btree.c c1308ba0b88ab577fa56c9e493a09829dfcded9c
 F src/test_config.c f0b911bb615d93a192647e76910dce65cbbcf3ad
@@ -504,6 +504,7 @@ F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b
 F tool/spaceanal.tcl f60a242a996a79d59cad6615cec83a9203e17911
 F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355
 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
+F www/34to35.tcl 5a477bf9210b324ee16bd26fc04ddd578b63b395
 F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf
 F www/arch.gif f845a64772062e82d17980a349f95f1f0b4c8054
 F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4
@@ -561,7 +562,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P 3d746343add3feb9d208302a00b419d71d6ba246
-R 95f58c79a104b4b1aa01178fe78f1fa0
-U danielk1977
-Z 8ec1ffcae0650e586d1badb059ab31f9
+P 5626ce0b5e249d48b56fdc4561ef663941eb23dc
+R 53f45ea77bc4d4516f85c7437592148c
+U drh
+Z edf7af5b96ec397985d0784a02a0916d
index ba5f676f170dda942636a2229a62de1655ff681c..350afa3baf1d3a824479bc738f051161ba4de8f0 100644 (file)
@@ -1 +1 @@
-5626ce0b5e249d48b56fdc4561ef663941eb23dc
\ No newline at end of file
+0791f917bb18d7305b805b9cbcb308bdd7b3a1f5
\ No newline at end of file
index e9150f1df9052dfe1271ae2dc0d217dee74d2c9f..1b23fef1ef04fc03a96c61bee6e4f3e17687b0ec 100644 (file)
@@ -2463,7 +2463,7 @@ static int unixAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){
     case SQLITE_ACCESS_READWRITE:
       amode = W_OK|R_OK;
       break;
-    case SQLITE_ACCESS_READONLY:
+    case SQLITE_ACCESS_READ:
       amode = R_OK;
       break;
 
index e87c416490dfba82417eb9be9a7ba753b7d75f52..36cce4f87c7bbfc5f3645ae68b52f6296a5eb5bc 100644 (file)
@@ -1237,15 +1237,13 @@ static int winAccess(
   }
   free(zConverted);
   switch( flags ){
+    case SQLITE_ACCESS_READ:
     case SQLITE_ACCESS_EXISTS:
       rc = attr!=0xffffffff;
       break;
     case SQLITE_ACCESS_READWRITE:
       rc = (attr & FILE_ATTRIBUTE_READONLY)==0;
       break;
-    case SQLITE_ACCESS_READONLY:
-      rc = (attr!=0xffffffff) && ((attr & FILE_ATTRIBUTE_READONLY)==1);
-      break;
     default:
       assert(!"Invalid flags argument");
   }
index edbffc8eb6b1e5bfdf85a97e802c9499e77420d4..3b1af5e9ccafdb4327ea5d9380b2054f1041613f 100644 (file)
@@ -30,7 +30,7 @@
 ** the version number) and changes its name to "sqlite3.h" as
 ** part of the build process.
 **
-** @(#) $Id: sqlite.h.in,v 1.243 2007/08/27 17:27:49 danielk1977 Exp $
+** @(#) $Id: sqlite.h.in,v 1.244 2007/08/27 21:10:36 drh Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
@@ -553,7 +553,7 @@ typedef struct sqlite3_mutex sqlite3_mutex;
 ** SQLite will guarantee that the zFilename string passed to
 ** xOpen() is a full pathname as generated by xFullPathname() and
 ** that the string will be valid and unchanged until xClose() is
-** called.  So the sqlite3_file can store a pointer to the
+** called.  So the [sqlite3_file] can store a pointer to the
 ** filename if it needs to remember the filename for some reason.
 **
 ** The flags argument to xOpen() is a copy of the flags argument
@@ -599,10 +599,10 @@ typedef struct sqlite3_mutex sqlite3_mutex;
 ** for exclusive access.  This flag is set for all files except
 ** for the main database file.
 ** 
-** The sqlite3_file structure passed as the third argument to
-** xOpen is allocated by the caller.  xOpen just fills it in.  The
-** caller allocates a minimum of szOsFile bytes for the sqlite3_file
-** structure.
+** Space to hold the  [sqlite3_file] structure passed as the third 
+** argument to xOpen is allocated by caller (the SQLite core). 
+** szOsFile bytes are allocated for this object.  The xOpen method
+** fills in the allocated space.
 ** 
 ** The flags argument to xAccess() may be 0 (to test for the
 ** existance of a file) or SQLITE_ACCESS_READWRITE to test to see
@@ -649,9 +649,21 @@ struct sqlite3_vfs {
   ** value will increment whenever this happens. */
 };
 
+/*
+** CAPI3REF: Flags for the xAccess VFS method
+**
+** These integer constants can be used as the third parameter to
+** the xAccess method of an [sqlite3_vfs] object.  They determine
+** the kind of what kind of permissions the xAccess method is
+** looking for.  With SQLITE_ACCESS_EXISTS, the xAccess method
+** simply checks to see if the file exists.  With SQLITE_ACCESS_READWRITE,
+** the xAccess method checks to see if the file is both readable
+** and writable.  With SQLITE_ACCESS_READ the xAccess method
+** checks to see if the file is readable.
+*/
 #define SQLITE_ACCESS_EXISTS    0
 #define SQLITE_ACCESS_READWRITE 1
-#define SQLITE_ACCESS_READONLY  2
+#define SQLITE_ACCESS_READ      2
 
 /*
 ** CAPI3REF: Enable Or Disable Extended Result Codes
index 572620c69cb0b96a6cbdb9a3fbf97170ac1fbaaa..1627f912fa8453c0d60ba9a787952f8c5b616fac 100644 (file)
@@ -726,7 +726,7 @@ static int asyncAccess(sqlite3_vfs *pAsyncVfs, const char *zName, int flags){
   sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;
 
   assert(flags==SQLITE_ACCESS_READWRITE 
-      || flags==SQLITE_ACCESS_READONLY 
+      || flags==SQLITE_ACCESS_READ 
       || flags==SQLITE_ACCESS_EXISTS 
   );
 
@@ -745,7 +745,7 @@ static int asyncAccess(sqlite3_vfs *pAsyncVfs, const char *zName, int flags){
   }
   ASYNC_TRACE(("ACCESS(%s): %s = %d\n", 
     flags==SQLITE_ACCESS_READWRITE?"read-write":
-    flags==SQLITE_ACCESS_READONLY?"read-only":"exists"
+    flags==SQLITE_ACCESS_READ?"read":"exists"
     , zName, ret)
   );
   pthread_mutex_unlock(&async.queueMutex);
diff --git a/www/34to35.tcl b/www/34to35.tcl
new file mode 100644 (file)
index 0000000..83c8c12
--- /dev/null
@@ -0,0 +1,966 @@
+#
+# Run this TCL script to generate HTML for the goals.html file.
+#
+set rcsid {$Id: 34to35.tcl,v 1.1 2007/08/27 21:10:36 drh Exp $}
+source common.tcl
+header {SQLite Changes From Version 3.4.2 To 3.5.0}
+
+proc CODE {text} {
+  puts "<blockquote><pre>"
+  puts $text
+  puts "</pre></blockquote>"
+}
+proc SYNTAX {text} {
+  puts "<blockquote><pre>"
+  set t2 [string map {& &amp; < &lt; > &gt;} $text]
+  regsub -all "/(\[^\n/\]+)/" $t2 {</b><i>\1</i><b>} t3
+  puts "<b>$t3</b>"
+  puts "</pre></blockquote>"
+}
+proc IMAGE {name {caption {}}} {
+  puts "<center><img src=\"$name\">"
+  if {$caption!=""} {
+    puts "<br>$caption"
+  }
+  puts "</center>"
+}
+proc PARAGRAPH {text} {
+  # regsub -all "/(\[a-zA-Z0-9\]+)/" $text {<i>\1</i>} t2
+  #regsub -all "\\*(\[^\n*\]+)\\*" $text {<tt><b><big>\1</big></b></tt>} t3
+  regsub -all {\[([^]\n]+)\]} $text {<b>\1</b>} t3
+  puts "<p>$t3</p>\n"
+}
+set level(0) 0
+set level(1) 0
+proc HEADING {n name {tag {}}} {
+  if {$tag!=""} {
+    puts "<a name=\"$tag\">"
+  }
+  global level
+  incr level($n)
+  for {set i [expr {$n+1}]} {$i<10} {incr i} {
+    set level($i) 0
+  }
+  if {$n==0} {
+    set num {}
+  } elseif {$n==1} {
+    set num $level(1).0
+  } else {
+    set num $level(1)
+    for {set i 2} {$i<=$n} {incr i} {
+      append num .$level($i)
+    }
+  }
+  incr n 1
+  puts "<h$n>$num $name</h$n>"
+}
+
+HEADING 0 {Moving From SQLite 3.4.2 to 3.5.0}
+
+PARAGRAPH {
+  SQLite version 3.5.0 introduces a new OS interface layer that
+  is incompatible with all prior versions of SQLite.  In addition,
+  a few existing interfaces have been generalized to work across all
+  database connections within a process rather than just all
+  connections within a thread.  The purpose of this article
+  is to describe the changes to 3.5.0 in detail so that users
+  of prior versions of SQLite can judge what, if any, effort will
+  be required to upgrade to newer versions.
+}
+
+HEADING 1 {Overview Of Changes}
+
+PARAGRAPH {
+  A quick enumeration of the changes in SQLite version 3.5.0
+  is provide here.  Subsequent sections will describe these
+  changes in more detail.
+}
+PARAGRAPH {
+  <ol>
+  <li>The OS interface layer has been completely reworked:
+  <ol type="a">
+  <li>The [sqlite3_os_switch()] interface has been removed.</li>
+  <li>The [SQLITE_ENABLE_REDEF_IO] compile-time flag no longer functions.
+      I/O procedures are now always redefinable.</li>
+  <li>Three new objects are defined for specifying I/O procedures:
+      [sqlite3_vfs], [sqlite3_file], and [sqlite3_io_methods].</li>
+  <li>Three new interfaces are used to create alternative OS interfaces:
+      [sqlite3_vfs_register()], [sqlite3_vfs_unregister()], and
+      [sqlite3_vfs_find()].</li>
+  <li>A new interface has been added to provided additional control over
+      the creation of new database connections: [sqlite3_open_v2()].
+      The legacy interfaces of [sqlite3_open()] and
+      [sqlite3_open16()] continue to be fully supported.</li>
+  </ol></li>
+  <li>The optional shared cache and memory management features that
+      were introduced in version 3.3.0 can now be used across multiple
+      threads within the same process.  Formerly, these extensions only
+      applied to database connections operating within a single thread.
+   <ol type="a">
+   <li>The [sqlite3_enable_shared_cache()] interface now applies to all
+       threads within a process, not to just the one thread in which it
+       was run.</li>
+   <li>The [sqlite3_soft_heap_limit()] interface now applies to all threads
+       within a process, not to just the one thread in which it was run.</li>
+   <li>The [sqlite3_release_memory()] interface will now attempt to reduce
+       the memory usages across all database connections in all threads, not
+       just connections in the thread where the interface is called.</li>
+   <li>The [sqlite3_thread_cleanup()] interface has become a no-op.</li>
+   </ol></li>
+  <li>Restrictions on the use of the same database connection by multiple
+      threads have been dropped.  It is now safe for
+      multiple threads to use the same database connection at the same
+      time.</li>
+  <li>There is now a compile-time option that allows an application to
+      define alternative malloc()/free() implementations without having
+      to modify any core SQLite code.</li>
+  <li>There is now a compile-time option that allows an application to
+      define alternative mutex implementations without having
+      to modify any core SQLite code.</li>
+  </ol>
+}
+PARAGRAPH {
+  Of these changes, only 1a and 2a through 2c are incompatibilities
+  in any formal sense.
+  But users who have previously made custom modifications to the
+  SQLite source (for example to add a custom OS layer for embedded
+  hardware) might find that these changes have a larger impact.
+  On the other hand, an important goal of these changes is to make
+  it much easier to customize SQLite for use on different operating
+  systems. 
+}
+
+HEADING 1 {The OS Interface Layer}
+
+PARAGRAPH {
+  If your system defines a custom OS interface for SQLite or if you
+  were using the (undocumented) [sqlite3_os_switch()]
+  interface, then you will need to make modifications in order to
+  upgrade to SQLite version 3.5.0.  This may seem painful at first
+  glance.  But as you look more closely, you will probably discover
+  that your changes are made smaller and easier to understand and manage
+  by the new SQLite interface.  It is likely that your changes will
+  now also work seamlessly with the SQLite amalgamation.  You will
+  no longer need to make any changes to the code SQLite source code.
+  All of your changes can be effected by application code and you can
+  link against a standard, unmodified version of the SQLite amalgamation.
+  Furthermore, the OS interface layer, which was formerly undocumented,
+  is now an officially support interface for SQLite.  So you have
+  some assurance that this will be a one-time change and that your
+  new backend will continue to work in future versions of SQLite.
+}
+
+HEADING 2 {The Virtual File System Object}
+
+PARAGRAPH {
+  The new OS interface for SQLite is built around an object named
+  [sqlite3_vfs].  The "vfs" standard for "Virtual File System".
+  The sqlite3_vfs object is basically a structure containing pointers
+  to functions that implement the primitive disk I/O operations that
+  SQLite needs to perform in order to read and write databases.  
+  In this article, we will often refer a sqlite3_vfs objects as a "VFS".
+}
+
+PARAGRAPH {
+  SQLite is able to use multiple VFSes at the same time.  Each
+  individual database connection is associated with just one VFS.
+  But if you have multiple database connections, each connection
+  can be associated with a different VFS.
+}
+
+PARAGRAPH {
+  There is always a default VFS.
+  The legacy interfaces [sqlite3_open()] and [sqlite3_open16()] always
+  use the default VFS.
+  The new interface for creating database connections,
+  [sqlite3_open_v2()], allows you to specify which VFS you want to
+  use by name.
+}
+
+HEADING 3 {Registering New VFS Objects}
+
+PARAGRAPH {
+  Standard builds of SQLite for unix or windows come with a single
+  VFS named "unix" or "win32", as appropriate.  This one VFS is also 
+  the default.  So if you are using the legacy open functions, everything
+  will continue to operate as it has before.  The change is that an application
+  now has the flexibility of adding new VFS modules to implement a
+  customized OS layer.  The [sqlite3_vfs_register()] API can be used
+  to tell SQLite about one or more application-defined VFS modules:
+}
+
+CODE {
+int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
+}
+
+PARAGRAPH {
+  Applications can call sqlite3_vfs_register at any time, though of course
+  a VFS needs to be registered before it can be used.  The first argument
+  is a pointer to a customized VFS object that the application has prepared.
+  The second argument is true to make the new VFS the default VFS so that
+  it will be used by the legacy [sqlite3_open()] and [sqlite3_open16()] APIs.
+  If the new VFS is not the default, then you will probably have to use
+  the new [sqlite3_open_v2()] API to use it.  Note, however, that if
+  a new VFS is the only VFS known to SQLite (if SQLite was compiled without
+  its usual default VFS or if the pre-compiled default VFS was removed
+  using [sqlite3_vfs_unregister()]) then the new VFS automatic becomes the
+  default VFS regardless of the makeDflt argument to [sqlite3_vfs_register()].
+}
+
+PARAGRAPH {
+  Standard builds include the default "unix" or "win32" VFSes.
+  But if you use the -DOS_OTHER=1 compile-time option, then SQLite is
+  built without a default VFS.  In that case, the application must
+  register at least one VFS prior to calling [sqlite3_open()].
+  This is the approach that embedded applications should use.
+  Rather than modifying the SQLite source to to insert an alternative
+  OS layer as was done in prior releases of SQLite, instead compile
+  an unmodified SQLite source file (preferably the amalgamation)
+  with the -DOS_OTHER=1 option, then invoke [sqlite3_vfs_register()]
+  to define the interface to the underlying filesystem prior to
+  creating any database connections.
+}
+
+HEADING 3 {Additional Control Over VFS Objects}
+
+PARAGRAPH {
+  The [sqlite3_vfs_unregister()] API is used to remove an existing
+  VFS from the system.
+}
+
+CODE {
+int sqlite3_vfs_unregister(sqlite3_vfs*);
+}
+
+PARAGRAPH {
+  The [sqlite3_vfs_find()] API is used to locate a particular VFS
+  by name.  Its prototype is as follows:
+}
+
+CODE {
+sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName);
+}
+
+PARAGRAPH {
+  The argument is the symbolic name for the desired VFS.  If the
+  argument is a NULL pointer, then the default VFS is returned.
+  The function returns a pointer to the [sqlite3_vfs] object that
+  implements the VFS.  Or it returns a NULL pointer if no object
+  could be found that matched the search criteria.
+}
+
+HEADING 3 {Modifications Of Existing VFSes}
+
+PARAGRAPH {
+  Once a VFS has been registered, it should never be modified.  If
+  a change in behavior is required, a new VFS should be registered.
+  The application could, perhaps, use [sqlite3_vfs_find()] to locate
+  the old VFS, make a copy of the old VFS into a new [sqlite3_vfs]
+  object, make the desired modifications to the new VFS, unregister
+  the old VFS, the register the new VFS in its place.  Existing
+  database connections would continue to use the old VFS even after
+  it is unregistered, but new database connections would use the
+  new VFS.
+}  
+
+HEADING 3 {The VFS Object}
+
+PARAGRAPH {
+  A VFS object is an instance of the following structure:
+}
+
+CODE {
+typedef struct sqlite3_vfs sqlite3_vfs;
+struct sqlite3_vfs {
+  int iVersion;            /* Structure version number */
+  int szOsFile;            /* Size of subclassed sqlite3_file */
+  int mxPathname;          /* Maximum file pathname length */
+  sqlite3_vfs *pNext;      /* Next registered VFS */
+  const char *zName;       /* Name of this virtual file system */
+  void *pAppData;          /* Pointer to application-specific data */
+  int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*,
+               int flags, int *pOutFlags);
+  int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir);
+  int (*xAccess)(sqlite3_vfs*, const char *zName, int flags);
+  int (*xGetTempName)(sqlite3_vfs*, char *zOut);
+  int (*xFullPathname)(sqlite3_vfs*, const char *zName, char *zOut);
+  void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename);
+  void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg);
+  void *(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol);
+  void (*xDlClose)(sqlite3_vfs*, void*);
+  int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut);
+  int (*xSleep)(sqlite3_vfs*, int microseconds);
+  int (*xCurrentTime)(sqlite3_vfs*, double*);
+  /* New fields may be appended in figure versions.  The iVersion
+  ** value will increment whenever this happens. */
+};
+}
+
+PARAGRAPH {
+  To create a new VFS, an application fills in an instance of this
+  structure with appropriate values and then calls [sqlite3_vfs_register()].
+}
+
+PARAGRAPH {
+  The iVersion field of [sqlite3_vfs] should be 1 for SQLite version 3.5.0.
+  This number may increase in future versions of SQLite if we have to
+  modify the VFS object in some way.  We hope that this never happens,
+  but the provision is made in case it does.
+}
+
+PARAGRAPH {
+  The szOsFile field is the size in bytes of the structure that defines
+  an open file: the [sqlite3_file] object.  This object will be described
+  more fully below.  The point here is that each VFS implementation can
+  define its own [sqlite3_file] object containing whatever information
+  the VFS implementation needs to store about an open file.  SQLite needs
+  to know how big this object is, however, in order to preallocate enough
+  space to hold it.
+}
+
+PARAGRAPH {
+  The mxPathname field is the maximum length of a file pathname that
+  this VFS can use.  SQLite sometimes has to preallocate buffers of
+  this size, so it should be as small as reasonably possible.  Some
+  filesystems permit huge pathnames, but in practice pathnames rarely
+  extend beyond 100 bytes or so.  You do not have to put the longest
+  pathname that the underlying filesystem can handle here.  You only
+  have to put the longest pathname that you want SQLite to be able to
+  handle.  A few hundred is a good value in most cases.
+}
+
+PARAGRAPH {
+  The pNext field is used internally by SQLite.  Specifically, SQLite
+  uses this field to form a linked list of registered VFSes.
+}
+
+PARAGRAPH {
+  The zName field is the symbolic name of the VFS.  This is the name 
+  that the [sqlite3_vfs_find()] compares against when it is looking for
+  a VFS.
+}
+
+PARAGRAPH {
+  The pAppData pointer is unused by the SQLite core.  The pointer is
+  available to store auxiliary information that a VFS information might
+  want to carry around.
+}
+
+PARAGRAPH {
+  The remaining fields of the [sqlite3_vfs] object all store pointer
+  to functions that implement primitive operations.  We call these
+  "methods".  The first methods, xOpen, is used to open files on
+  the underlying storage media.  The result is an [sqlite3_file]
+  object.  There are additional methods, defined by the [sqlite3_file]
+  object itself that are used to read and write and close the file.
+  The additional methods are detailed below.  The filename is in UTF-8.
+  SQLite will guarantee that the zFilename string passed to
+  xOpen() is a full pathname as generated by xFullPathname() and
+  that the string will be valid and unchanged until xClose() is
+  called.  So the [sqlite3_file] can store a pointer to the
+   filename if it needs to remember the filename for some reason.
+   The flags argument to xOpen() is a copy of the flags argument
+   to sqlite3_open_v2().  If sqlite3_open() or sqlite3_open16()
+   is used, then flags is SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE.
+   If xOpen() opens a file read-only then it sets *pOutFlags to
+   include SQLITE_OPEN_READONLY.  Other bits in *pOutFlags may be
+   set.
+   SQLite will also add one of the following flags to the xOpen()
+   call, depending on the object being opened:
+   <ul>
+   <li>  [SQLITE_OPEN_MAIN_DB]
+   <li>  [SQLITE_OPEN_MAIN_JOURNAL]
+   <li>  [SQLITE_OPEN_TEMP_DB]
+   <li>  [SQLITE_OPEN_TEMP_JOURNAL]
+   <li>  [SQLITE_OPEN_SUBJOURNAL]
+   <li>  [SQLITE_OPEN_MASTER_JOURNAL]
+   </ul>
+   The file I/O implementation can use the object type flags to
+   changes the way it deals with files.  For example, an application
+   that does not care about crash recovery or rollback, might make
+   the open of a journal file a no-op.  Writes to this journal are
+   also a no-op.  Any attempt to read the journal return SQLITE_IOERR.
+   Or the implementation might recognize the a database file will
+   be doing page-aligned sector reads and writes in a random order
+   and set up its I/O subsystem accordingly.
+   SQLite might also add one of the following flags to the xOpen
+   method:
+   <ul>
+   <li> [SQLITE_OPEN_DELETEONCLOSE]
+   <li> [SQLITE_OPEN_EXCLUSIVE]
+   </ul>
+   The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be
+   deleted when it is closed.  This will always be set for TEMP 
+   databases and journals and for subjournals.  The 
+   [SQLITE_OPEN_EXCLUSIVE] flag means the file should be opened
+   for exclusive access.  This flag is set for all files except
+   for the main database file.
+   The [sqlite3_file] structure passed as the third argument to
+   xOpen is allocated by the caller.  xOpen just fills it in.  The
+   caller allocates a minimum of szOsFile bytes for the [sqlite3_file]
+   structure.
+}
+
+PARAGRAPH {
+  The xDelete method is used delete a file.  The name of the file is
+  given in the second parameter.  The filename will be in UTF-8.
+  The VFS must convert the filename into whatever character representation
+  the underlying operating system expects.  If the syncDir parameter is
+  true, then the xDelete method should not return until the change
+  to the directory contents for the directory containing the
+  deleted file have been synced to disk in order to insure that the
+  file does not "reappear" if a power failure occurs soon after.
+}
+
+PARAGRAPH {
+  The xAccess method is used to check for access permissions on a file.
+  The filename will be UTF-8 encoded.  The flags argument will be
+  SQLITE_ACCESS_EXISTS to check for the existence of the file,
+  SQLITE_ACCESS_READWRITE to check to see if the file is both readable
+  and writable, or SQLITE_ACCESS_READ to check to see if the file is
+  at least readable.  The "file" named by the second parameter might
+  be a directory or folder name.
+}
+
+PARAGRAPH {
+  The xGetTempName method computes the name of a temporary file that
+  SQLite can use.  The name should be written into the buffer given
+  by the second parameter.  SQLite will size that buffer to hold
+  at least mxPathname bytes.  The generated filename should be in UTF-8.
+  To avoid security problems, the generated temporary filename should
+  contain enough randomness to prevent an attacker from guessing the
+  temporary filename in advance.
+}
+
+PARAGRAPH {
+  The xFullPathname method is used to convert a relative pathname
+  into a full pathname.  The resulting full pathname is written into
+  the buffer provided by the third parameter.  SQLite will size the
+  output buffer to at least mxPathname bytes.  Both the input and
+  output names should be in UTF-8.
+}
+
+PARAGRAPH {
+  The xDlOpen, xDlError, xDlSym, and xDlClose methods are all used for
+  accessing shared libraries at run-time.  These methods may be omitted
+  (and their pointers set to zero) if the library is compiled with
+  SQLITE_OMIT_LOAD_EXTENSION or if the [sqlite3_enable_load_extension()]
+  interface is never used to enable dynamic extension loading.  The
+  xDlOpen method opens a shared library or DLL and returns a pointer to
+  a handle.  NULL is returned if the open fails.  If the open fails,
+  the xDlError method can be used to obtain a text error message.
+  The message is written into the zErrMsg buffer of the third parameter
+  which is at least nByte bytes in length.  The xDlSym returns a pointer
+  to a symbol in the shared library.  The name of the symbol is given
+  by the second parameter.  UTF-8 encoding is assumed.  If the symbol
+  is not found a NULL pointer is returned.  The xDlClose routine closes
+  the shared library.
+}
+
+PARAGRAPH {
+  The xRandomness method is used once by the first database connection
+  that is opened.  xRandomness should return high-quality randomness
+  that SQLite will used to seeds its internal pseudo-random number
+  generator (PRNG).  The routine requests that nByte bytes of randomness
+  be written into zOut.  The routine returns the actual number of
+  bytes of randomness obtained.  The quality of the randomness so obtained
+  will determine the quality of the randomness generated by built-in 
+  SQLite functions such as random() and randomblob().
+}
+
+PARAGRAPH {
+  The xSleep method is used to suspend the calling thread for at
+  least the number of microseconds given.  This method is used to
+  implement the [sqlite3_sleep()] and [sqlite3_busy_timeout()] APIs.
+  In the case of [sqlite3_sleep()] the xSleep method of the default
+  VFS is always used.  If the underlying system does not have a
+  microsecond resolution sleep capability, then the sleep time should
+  be rounded up.  xSleep returns this rounded-up value.
+}
+
+PARAGRAPH {
+  The xCurrentTime method finds the current time and date and writes
+  the result as double-precision floating point value into pointer
+  provided by the second parameter.  The time and date is in
+  coordinated universal time (UTC) and is a fractional julian day number.
+}
+
+HEADING 3 {The Open File Object}
+
+PARAGRAPH {
+  The result of opening a file is an instance of an [sqlite3_file] object.
+  The [sqlite3_file] object is an abstract base class defined as follows:
+}
+
+CODE {
+typedef struct sqlite3_file sqlite3_file;
+struct sqlite3_file {
+  const struct sqlite3_io_methods *pMethods;
+};
+}
+
+PARAGRAPH {
+  Each VFS implementation will subclass the [sqlite3_file] by adding
+  additional fields at the end to hold whatever information the VFS
+  needs to know about an open file.  It does not matter what information
+  is stored as long as the total size of the structure does not exceed
+  the szOsFile value recorded in the [sqlite3_vfs] object.
+}
+
+PARAGRAPH {
+  The [sqlite3_io_methods] object is a structure that contains pointers
+  to methods for reading, writing, and otherwise dealing with files.
+  This object is defined as follows:
+}
+
+CODE {
+typedef struct sqlite3_io_methods sqlite3_io_methods;
+struct sqlite3_io_methods {
+  int iVersion;
+  int (*xClose)(sqlite3_file*);
+  int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite_int64 iOfst);
+  int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite_int64 iOfst);
+  int (*xTruncate)(sqlite3_file*, sqlite_int64 size);
+  int (*xSync)(sqlite3_file*, int flags);
+  int (*xFileSize)(sqlite3_file*, sqlite_int64 *pSize);
+  int (*xLock)(sqlite3_file*, int);
+  int (*xUnlock)(sqlite3_file*, int);
+  int (*xCheckReservedLock)(sqlite3_file*);
+  int (*xBreakLock)(sqlite3_file*);
+  int (*xLockState)(sqlite3_file *);
+  int (*xSectorSize)(sqlite3_file*);
+  int (*xDeviceCharacteristics)(sqlite3_file*);
+  /* Additional methods may be added in future releases */
+};
+}
+
+PARAGRAPH {
+  The iVersion field of [sqlite3_io_methods] is provided as insurance
+  against future enhancements.  The iVersion value should always be
+  1 for SQLite version 3.5.
+}
+
+PARAGRAPH {
+  The xClose method closes the file.  The space for the [sqlite3_file]
+  structure is deallocated by the caller.  But if the [sqlite3_file]
+  contains pointers to other allocated memory or resources, those
+  allocations should be released by the xClose method.
+}
+
+PARAGRAPH {
+  The xRead method reads iAmt bytes from the file beginning at a byte
+  offset to iOfst.  The data read is stored in the pointer of the
+  second parameter.  xRead returns the SQLITE_OK on success,
+  SQLITE_IOERR_SHORT_READ if it was not able to read the full number
+  of bytes because it reached end-of-file, or SQLITE_IOERR_READ for
+  any other error.
+}
+
+PARAGRAPH {
+  The xWrite method writes iAmt bytes of data from the second parameter
+  into the file beginning at an offset of iOfst bytes.  If the size of
+  the file is less than iOfst bytes prior to the write, then xWrite should
+  ensure that the file is extended with zeros up to iOfst bytes prior
+  to beginning its write.  xWrite continues to extends the file as
+  necessary so that the size of the file is at least iAmt+iOfst bytes 
+  at the conclusion of the xWrite call.  The xWrite method returns
+  SQLITE_OK on success.  If the write cannot complete because the
+  underlying storage medium is full, then SQLITE_FULL is returned.
+  SQLITE_IOERR_WRITE should be returned for any other error.
+}
+
+PARAGRAPH {
+  The xTruncate method truncates a file to be nByte bytes in length.
+  If the file is already nByte bytes or less in length then this
+  method is a no-op.  The xTruncate method returns SQLITE_OK on
+  success and SQLITE_IOERR_TRUNCATE if anything goes wrong.
+}
+
+PARAGRAPH {
+  The xSync method is used to force previously written data out of
+  operating system cache and into non-volatile memory.  The second
+  parameter is usually SQLITE_SYNC_NORMAL.  If the second parameter
+  is SQLITE_SYNC_FULL then the xSync method should make sure that
+  data has also been flushed through the disk controllers cache.
+  The SQLITE_SYNC_FULL parameter is the equivalent of the F_FULLSYNC
+  ioctl() on Mac OS X.  The SQLITE_SYNC_BARRIER is currently unused.
+  In the future this value might request that the xSync call serve
+  as an I/O barrier operation.  All write requests that occur before
+  the xSync must complete before any write request that occurs
+  afterwards, but the barrier does not require that all writes 
+  complete prior to the return of xSync.  The xSync method returns
+  SQLITE_OK on success and SQLITE_IOERR_FSYNC if anything goes wrong.
+}
+
+PARAGRAPH {
+  The xFileSize() method determines the current size of the file
+  in bytes and writes that value into *pSize.  It returns SQLITE_OK
+  on success and SQLITE_IOERR_FSTAT if something goes wrong.
+}
+
+PARAGRAPH {
+  The xLock and xUnlock methods are used to set and clear file locks.
+  SQLite supports five levels of file locks, in order:
+  <ul>
+  <li> [SQLITE_LOCK_NONE]
+  <li> [SQLITE_LOCK_SHARED]
+  <li> [SQLITE_LOCK_RESERVED]
+  <li> [SQLITE_LOCK_PENDING]
+  <li> [SQLITE_LOCK_EXCLUSIVE]
+  </ul>
+  The underlying implementation can support some subset of these locking
+  levels as long as it meets the other requirements of this paragraph.
+  The locking level is specified as the second argument to both xLock
+  and xUnlock.  The xLock method increases the locking level to the
+  specified locking level or higher.  The xUnlock method decreases the
+  locking level to no lower than the level specified.  
+  SQLITE_LOCK_NONE means that the file is unlocked.  SQLITE_LOCK_SHARED
+  gives permission to read the file.  Multiple database connections can
+  hold SQLITE_LOCK_SHARED at the same time.
+  SQLITE_LOCK_RESERVED is like SQLITE_LOCK_SHARED in that its is permission
+  to read the file.  But only a single connection can hold a reserved lock
+  at any point in time.  The SQLITE_LOCK_PENDING is also permission to
+  read the file.  Other connections can continue to read the file as well,
+  but no other connection is allowed to escalate a lock from none to shared.
+  SQLITE_LOCK_EXCLUSIVE is permission to write on the file.  Only a single
+  connection can hold an exclusive lock and no other connection can hold
+  any lock (other than "none") while one connection is hold an exclusive
+  lock.  The xLock returns SQLITE_OK on success, SQLITE_BUSY if it
+  is unable to obtain the lock, or SQLITE_IOERR_RDLOCK if something else
+  goes wrong.  The xUnlock method returns SQLITE_OK on success and
+  SQLITE_IOERR_UNLOCK for problems.
+}
+
+PARAGRAPH {
+  The xCheckReservedLock method checks to see if another connection or
+  another process is currently holding a reserved, pending, or exclusive
+  lock on the file.  It returns true or false.
+}
+
+PARAGRAPH {
+  The xLockState method returns one of the [SQLITE_LOCK_NONE] through
+  [SQLITE_LOCK_EXCLUSIVE] constants defined above to indicate the current
+  state of the lock for the given file handle.  This method is used for
+  testing purposes only.
+}
+
+PARAGRAPH {
+  The xSectorSize returns the "sector size" of the underlying
+  non-volatile media.  A "sector" is defined as the smallest unit of
+  storage that can be written without disturbing adjacent storage.
+  On a disk drive the "sector size" has until recently been 512 bytes,
+  though there is a push to increase this value to 4KiB.  SQLite needs
+  to know the sector size so that it can write a full sector at a
+  time, and thus avoid corrupting adjacent storage space if a power
+  lose occurs in the middle of a write.
+}
+
+PARAGRAPH {
+  The xDeviceCharacteristics method returns an integer bit vector that
+  defines any special properties that the underlying storage medium might
+  have that SQLite can use to increase performance.  The allowed return
+  is the bit-wise OR of the following values:
+  <ul>
+  <li> SQLITE_IOCAP_ATOMIC
+  <li> SQLITE_IOCAP_ATOMIC512
+  <li> SQLITE_IOCAP_ATOMIC1K
+  <li> SQLITE_IOCAP_ATOMIC2K
+  <li> SQLITE_IOCAP_ATOMIC4K
+  <li> SQLITE_IOCAP_ATOMIC8K
+  <li> SQLITE_IOCAP_ATOMIC16K
+  <li> SQLITE_IOCAP_ATOMIC32K
+  <li> SQLITE_IOCAP_ATOMIC64K
+  <li> SQLITE_IOCAP_SAFE_APPEND
+  <li> SQLITE_IOCAP_SEQUENTIAL
+  </ul>
+  The SQLITE_IOCAP_ATOMIC bit means that all writes to this device are
+  atomic in the sense that either the entire write occurs or none of it
+  occurs.  The other SQLITE_IOCAP_ATOMIC<i>nnn</i> values indicate that
+  writes of aligned blocks of the indicated size are atomic.
+  SQLITE_IOCAP_SAFE_APPEND means that when extending a file with new
+  data, the new data is written first and then the file size is updated.
+  So if a power failure occurs, there is no chance that the file might have
+  been extended with randomness.  The SQLITE_IOCAP_SEQUENTIAL bit means
+  that all writes occur in the order that they are issued and are not
+  reordered by the underlying file system.
+}
+
+HEADING 3 {Checklist For Constructing A New VFS}
+
+PARAGRAPH {
+  The preceding paragraphs contain a lot of information.
+  To ease the task of constructing
+  a new VFS for SQLite we offer the following implementation checklist:
+}
+
+PARAGRAPH {
+  <ol>
+  <li> Define an appropriate subclass of the [sqlite3_file] object.
+  <li> Implement the methods required by the [sqlite_io_methods] object.
+  <li> Create a static and 
+       constant [sqlite3_io_methods] object containing pointers
+       to the methods from the previous step.
+  <li> Implement the xOpen method that opens a file and populates an
+       [sqlite3_file] object, including setting pMethods to
+       point to the [sqlite3_io_methods] object from the previous step.
+  <li> Implement the other methods required by [sqlite3_vfs].
+  <li> Define a static (but not constant) [sqlite3_vfs] structure that
+       contains pointers to the xOpen method and the other methods and
+       which contains the appropriate values for iVersion, szOsFile,
+       mxPathname, zName, and pAppData.
+  <li> Implement a procedure that calls [sqlite3_vfs_register()] and
+       passes it a pointer to the [sqlite3_vfs] structure from the previous
+       step.  This procedure is probably the only exported symbol in the
+       source file that implements your VFS.
+  </ol>
+}
+
+PARAGRAPH {
+  Within your application, call the procedure implemented in the last
+  step above as part of your initialization process before any
+  database connections are opened.  
+}
+
+HEADING 1 {The Memory Allocation Subsystem}
+
+PARAGRAPH {
+  Beginning with version 3.5, SQLite obtains all of the heap memory it
+  needs using the routines [sqlite3_malloc()], [sqlite3_free()], and
+  [sqlite3_realloc()].  These routines have existed in prior versions
+  of SQLite, but SQLite has previously bypassed these routines and used
+  its own memory allocator.  This all changes in version 3.5.0.
+}
+
+PARAGRAPH {
+  The SQLite source tree actually contains multiple versions of the
+  memory allocator.  The default high-speed version found in the
+  "mem1.c" source file is used for most builds.  But if the SQLITE_MEMDEBUG
+  flag is enabled, a separate memory allocator the "mem2.c" source file
+  is used instead.  The mem2.c allocator implements lots of hooks to
+  do error checking and to simulate memory allocation failures for testing
+  purposes.  Both of these allocators use the malloc()/free() implementation
+  in the standard C library.
+}
+
+PARAGRAPH {
+  Applications are not required to use either of these standard memory
+  allocators.  If SQLite is compiled with SQLITE_OMIT_MEMORY_ALLOCATION
+  then no implementation for the [sqlite3_malloc()], [sqlite3_realloc()],
+  and [sqlite3_free()] functions is provided.  Instead, the application
+  that links against SQLite must provide its own implementation of these
+  functions.  The application provided memory allocator is not required
+  to use the malloc()/free() implementation in the standard C library.
+  An embedded application might provide an alternative memory allocator
+  that uses memory for a fixed memory pool set aside for the exclusive
+  use of SQLite, for example.
+}
+
+PARAGRAPH {
+  Applications that implement their own memory allocator must provide
+  implementation for the usual three allocation functions 
+  [sqlite3_malloc()], [sqlite3_realloc()], and [sqlite3_free()].
+  And they must also implement a fourth function:
+}
+
+CODE {
+int sqlite3_memory_alarm(
+  void(*xCallback)(void *pArg, sqlite3_int64 used, int N),
+  void *pArg,
+  sqlite3_int64 iThreshold
+);
+}
+
+PARAGRAPH {
+ The [sqlite3_memory_alarm] routine is used to register
+ a callback on memory allocation events.
+ This routine registers or clears a callbacks that fires when
+ the amount of memory allocated exceeds iThreshold.  Only
+ a single callback can be registered at a time.  Each call
+ to [sqlite3_memory_alarm()] overwrites the previous callback.
+ The callback is disabled by setting xCallback to a NULL
+ pointer.
+}
+
+PARAGRAPH {
+ The parameters to the callback are the pArg value, the 
+ amount of memory currently in use, and the size of the
+ allocation that provoked the callback.  The callback will
+ presumably invoke [sqlite3_free()] to free up memory space.
+ The callback may invoke [sqlite3_malloc()] or [sqlite3_realloc()]
+ but if it does, no additional callbacks will be invoked by
+ the recursive calls.
+}
+
+PARAGRAPH {
+ The [sqlite3_soft_heap_limit()] interface works by registering
+ a memory alarm at the soft heap limit and invoking 
+ [sqlite3_release_memory()] in the alarm callback.  Application
+ programs should not attempt to use the [sqlite3_memory_alarm()]
+ interface because doing so will interfere with the
+ [sqlite3_soft_heap_limit()] module.  This interface is exposed
+ only so that applications can provide their own
+ alternative implementation when the SQLite core is
+ compiled with SQLITE_OMIT_MEMORY_ALLOCATION.
+}
+
+PARAGRAPH {
+  The built-in memory allocators in SQLite also provide the following
+  additional interfaces:
+}
+
+CODE {
+sqlite3_int64 sqlite3_memory_used(void);
+sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
+}
+
+PARAGRAPH {
+  These interfaces can be used by an application to monitor how
+  much memory SQLite is using.  The [sqlite3_memory_used()] routine
+  returns the number of bytes of memory currently in use and the
+  [sqlite3_memory_highwater()] returns the maximum instantaneous
+  memory usage.  Neither routine includes the overhead associated
+  with the memory allocator.  These routines are provided for use
+  by the application.  SQLite never invokes them itself.  So if
+  the application is providing its own memory allocation subsystem,
+  it can omit these interfaces if desired.
+}
+
+HEADING 1 {The Mutex Subsystem}
+
+PARAGRAPH {
+  SQLite has always been threadsafe in the sense that it is safe to
+  use different SQLite database connections in different threads at the
+  same time.  The constraint was that the same database connection
+  could not be used in two separate threads at once.  SQLite version 3.5.0
+  relaxes this constraint. 
+}
+
+PARAGRAPH {
+  In order to allow multiple threads to use the same database connection
+  at the same time, SQLite must make extensive use of mutexes.  And for
+  this reason a new mutex subsystem as been added.  The mutex subsystem
+  as the following interface:
+}
+
+CODE {
+sqlite3_mutex *sqlite3_mutex_alloc(int);
+void sqlite3_mutex_free(sqlite3_mutex*);
+void sqlite3_mutex_enter(sqlite3_mutex*);
+int sqlite3_mutex_try(sqlite3_mutex*);
+void sqlite3_mutex_leave(sqlite3_mutex*);
+}
+
+PARAGRAPH {
+  Though these routines exist for the use of the SQLite core, 
+  application code is free to use these routines as well, if desired.
+  A mutex is an [sqlite3_mutex] object.  The [sqlite3_mutex_alloc()]
+  routine allocates a new mutex object and returns a pointer to it.
+  The argument to [sqlite3_mutex_alloc()] should be 
+  [SQLITE_MUTEX_FAST] or [SQLITE_MUTEX_RECURSIVE] for non-recursive
+  and recursive mutexes, respectively.  If the underlying system does
+  not provide non-recursive mutexes, then a recursive mutex can be
+  substituted in that case.  The argument to [sqlite3_mutex_alloc()]
+  can also be a constant designating one of several static mutexes:
+  <ul>
+  <li>  SQLITE_MUTEX_STATIC_MASTER
+  <li>  SQLITE_MUTEX_STATIC_MEM
+  <li>  SQLITE_MUTEX_STATIC_MEM2
+  <li>  SQLITE_MUTEX_STATIC_PRNG
+  </ul>
+  These static mutexes are reserved for use internally by SQLite
+  and should not be used by the application.  The static mutexes
+  are all non-recursive.
+}
+
+PARAGRAPH {
+  The [sqlite3_mutex_free()] routine should be used to deallocate
+  a non-static mutex.  If a static mutex is passed to this routine
+  then the behavior is undefined.
+}
+
+PARAGRAPH {
+  The [sqlite3_mutex_enter()] attempts to enter the mutex and blocks
+  if another threads is already there.  [sqlite3_mutex_try()] attempts
+  to enter and returns SQLITE_OK on success or SQLITE_BUSY if another
+  thread is already there.  [sqlite3_mutex_leave()] exits a mutex.
+  The mutex is held until the number of exits matches the number of
+  entrances.  If [sqlite3_mutex_leave()] is called on a mutex that 
+  the thread is not currently holding, then the behavior is undefined.
+  If any routine is called for a deallocated mutex, then the behavior
+  is undefined.
+}
+
+PARAGRAPH {
+  The SQLite source code provides multiple implementations of these
+  APIs, suitable for varying environments.  If SQLite is compiled with
+  the SQLITE_THREADSAFE=0 flag then a no-op mutex implementation that 
+  is fast but does no real mutual exclusion is provided.  That 
+  implementation is suitable for use in single-threaded applications
+  or applications that only use SQLite in a single thread.  Other
+  real mutex implementations are provided based on the underlying
+  operating system.
+}
+
+PARAGRAPH {
+  Embedded applications may wish to provide their own mutex implementation.
+  If SQLite is compiled with the -DSQLITE_MUTEX_APPDEF=1 compile-time flag
+  then the SQLite core provides no mutex subsystem and a mutex subsystem
+  that matches the interface described above must be provided by the
+  application that links against SQLite.
+}
+
+HEADING 1 {Other Interface Changes}
+
+PARAGRAPH {
+  Version 3.5.0 of SQLite changes the behavior of a few APIs in ways
+  that are technically incompatible.  However, these APIs are seldom
+  used and even when they are used it is difficult to imagine a
+  scenario where the change might break something.  The changes
+  actually makes these interface much more useful and powerful.
+}
+
+PARAGRAPH {
+  Prior to version 3.5.0, the [sqlite3_enable_shared_cache()] API
+  would enable and disable the shared cache feature for all connections
+  within a single thread - the same thread from which the 
+  sqlite3_enable_shared_cache() routine was called.  Database connections
+  that used the shared cache were restricted to running in the same
+  thread in which they were opened.  Beginning with version 3.5.0,
+  the sqlite3_enable_shared_cache() applies to all database connections
+  in all threads within the process.  Now database connections running
+  in separate threads can share a cache.  And database connections that
+  use shared cache can migrate from one thread to another.
+}
+
+PARAGRAPH {
+  Prior to version 3.5.0 the [sqlite3_soft_heap_limit()] set an upper
+  bound on heap memory usage for all database connections within a
+  single thread.  Each thread could have its own heap limit.  Beginning
+  in version 3.5.0, there is a single heap limit for the entire process.
+  This seems more restrictive (one limit as opposed to many) but in
+  practice it is what most users want.
+}
+
+PARAGRAPH {
+  Prior to version 3.5.0 the [sqlite3_release_memory()] function would
+  try to reclaim memory from all database connections in the same thread
+  as the sqlite3_release_memory() call.  Beginning with version 3.5.0,
+  the sqlite3_release_memory() function will attempt to reclaim memory
+  from all database connections in all threads.
+}
+
+HEADING 1 {Summary}
+
+PARAGRAPH {
+  The transition from SQLite version 3.4.2 to 3.5.0 is a major change.
+  Every source code file in the SQLite core had to be modified, some
+  extensively.  And the change introduced some minor incompatibilities
+  in the C interface.  But we feel that the benefits of the transition
+  from 3.4.2 to 3.5.0 far outweigh the pain of porting.  The new
+  VFS layer is now well-defined and stable and should simplify future
+  customizations.  The VFS layer, and the separable memory allocator
+  and mutex subsystems allow a standard SQLite source code amalgamation
+  to be used in an embedded project without change, greatly simplifying
+  configuration management.  And the resulting system is much more
+  tolerant of highly threaded designs.
+}