System.Data.SQLite
Check-in [2f90848c8e]
Not logged in

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

Overview
Comment:Add the ability to select the legacy connection closing algorithm at compile-time.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | legacyClose
Files: files | file ages | folders
SHA1: 2f90848c8e495f2ebb9542a6d2035af93fd6b318
User & Date: mistachkin 2013-02-15 01:14:17
Context
2013-02-15
04:36
Fix compilation and test issues with the INTEROP_LEGACY_CLOSE compile-time option. Closed-Leaf check-in: a75bb0a659 user: mistachkin tags: legacyClose
01:14
Add the ability to select the legacy connection closing algorithm at compile-time. check-in: 2f90848c8e user: mistachkin tags: legacyClose
2013-02-13
21:59
Add doc wording to clarify that the connection pool will not work properly in WPF applications. Pursuant to [393d954be0]. check-in: dabfe38a9e user: mistachkin tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to SQLite.Interop/src/win/interop.c.

    73     73   SQLITE_PRIVATE int logConfigured = 0;
    74     74   
    75     75   SQLITE_PRIVATE void sqlite3InteropLogCallback(void *pArg, int iCode, const char *zMsg){
    76     76     sqlite3InteropDebug("INTEROP_LOG (%d) %s\n", iCode, zMsg);
    77     77   }
    78     78   #endif
    79     79   
    80         -#if SQLITE_VERSION_NUMBER < 3007014
           80  +#if defined(INTEROP_LEGACY_CLOSE) || SQLITE_VERSION_NUMBER < 3007014
    81     81   SQLITE_PRIVATE void * sqlite3DbMallocZero_interop(sqlite3 *db, int n)
    82     82   {
    83     83     void *p;
    84     84     if (db) {
    85     85       sqlite3_mutex_enter(db->mutex);
    86     86     }
    87     87     p = sqlite3DbMallocZero(db,n);
................................................................................
   118    118       that memory was deallocated.  BAD.  So, what we need to do is make a copy of each statement, and call finalize() on the copy -- so that the original
   119    119       statement's memory is preserved, and marked as BAD, but we can still manage to finalize everything and forcibly close the database.  Later when the 
   120    120       GC gets around to calling finalize_interop() on the "bad" statement, we detect that and finish deallocating the pointer.
   121    121   */
   122    122   SQLITE_API int WINAPI sqlite3_close_interop(sqlite3 *db)
   123    123   {
   124    124     int ret;
   125         -#if SQLITE_VERSION_NUMBER >= 3007014
          125  +#if !defined(INTEROP_LEGACY_CLOSE) && SQLITE_VERSION_NUMBER >= 3007014
   126    126   
   127    127   #if defined(INTEROP_DEBUG) && (INTEROP_DEBUG & INTEROP_DEBUG_CLOSE)
   128    128     sqlite3InteropDebug("sqlite3_close_interop(): calling sqlite3_close_v2(%p)...\n", db);
   129    129   #endif
   130    130   
   131    131     ret = sqlite3_close_v2(db);
   132    132   
................................................................................
   401    401     *plen = (pval != 0) ? wcslen((wchar_t *)pval) * sizeof(wchar_t): 0;
   402    402     return pval;
   403    403   }
   404    404   
   405    405   SQLITE_API int WINAPI sqlite3_finalize_interop(sqlite3_stmt *stmt)
   406    406   {
   407    407     int ret;
   408         -#if SQLITE_VERSION_NUMBER >= 3007014
          408  +#if !defined(INTEROP_LEGACY_CLOSE) && SQLITE_VERSION_NUMBER >= 3007014
   409    409   
   410    410   #if defined(INTEROP_DEBUG) && (INTEROP_DEBUG & INTEROP_DEBUG_FINALIZE)
   411    411     Vdbe *p = (Vdbe *)stmt;
   412    412     sqlite3 *db = p->db;
   413    413     sqlite3InteropDebug("sqlite3_finalize_interop(): calling sqlite3_finalize(%p, %p)...\n", db, stmt);
   414    414   #endif
   415    415   
................................................................................
   467    467   
   468    468     return ret;
   469    469   }
   470    470   
   471    471   SQLITE_API int WINAPI sqlite3_reset_interop(sqlite3_stmt *stmt)
   472    472   {
   473    473     int ret;
   474         -#if SQLITE_VERSION_NUMBER >= 3007014
          474  +#if !defined(INTEROP_LEGACY_CLOSE) && SQLITE_VERSION_NUMBER >= 3007014
   475    475   
   476    476   #if defined(INTEROP_DEBUG) && (INTEROP_DEBUG & INTEROP_DEBUG_RESET)
   477    477     sqlite3InteropDebug("sqlite3_reset_interop(): calling sqlite3_reset(%p)...\n", stmt);
   478    478   #endif
   479    479   
   480    480     ret = sqlite3_reset(stmt);
   481    481   

Changes to SQLite.NET.Settings.targets.

   276    276                     INTEROP_DEBUG_RESET          (0x0080)
   277    277                     INTEROP_DEBUG_CHANGES        (0x0100)
   278    278                     INTEROP_DEBUG_BREAK          (0x0200)
   279    279       -->
   280    280       <InteropDebug Condition="'$(InteropDebug)' == '' And '$(Configuration)' == 'Debug'">true</InteropDebug>
   281    281       <InteropDebug Condition="'$(InteropDebug)' == '' And '$(Configuration)' != 'Debug'">false</InteropDebug>
   282    282   
          283  +    <!--
          284  +        NOTE: Disable all use of the sqlite3_close_v2() native API and use the
          285  +              legacy System.Data.SQLite connection closing algorithm instead.
          286  +              By default, this is disabled.  If this is enabled, it must also
          287  +              be enabled via the "INTEROP_LEGACY_CLOSE=1" preprocessor define
          288  +              being present in the "INTEROP_EXTRA_DEFINES" macro in the build
          289  +              properties file:
          290  +
          291  +                  "SQLite.Interop\props\SQLite.Interop.20YY.[vs]props"
          292  +
          293  +              for the corresponding version(s) of Visual Studio.
          294  +    -->
          295  +    <InteropLegacyClose Condition="'$(InteropLegacyClose)' == ''">false</InteropLegacyClose>
          296  +
   283    297       <!--
   284    298           NOTE: Enable the logging callback in the custom built interop DLL (i.e.
   285    299                 "SQLite.Interop.dll")?  By default, this is enabled in the Debug
   286    300                 build configuration.  If this is disabled, the logging callback
   287    301                 will be unavailable and diagnostic messages may not be seen if
   288    302                 another native logging callback is not configured.  If this is
   289    303                 enabled, it must also be enabled via the "INTEROP_LOG=1"

Changes to System.Data.SQLite/SQLiteBase.cs.

   592    592                   SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_close(db);
   593    593   #endif
   594    594                   if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError(hdl, db));
   595    595               }
   596    596           }
   597    597       }
   598    598   
          599  +#if !INTEROP_LEGACY_CLOSE
   599    600       internal static void CloseConnectionV2(SQLiteConnectionHandle hdl, IntPtr db)
   600    601       {
   601    602           if ((hdl == null) || (db == IntPtr.Zero)) return;
   602    603   
   603    604           try
   604    605           {
   605    606               // do nothing.
................................................................................
   619    620   
   620    621                   SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_close_v2(db);
   621    622   #endif
   622    623                   if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError(hdl, db));
   623    624               }
   624    625           }
   625    626       }
          627  +#endif
   626    628   
   627    629       internal static bool ResetConnection(SQLiteConnectionHandle hdl, IntPtr db, bool canThrow)
   628    630       {
   629    631           if ((hdl == null) || (db == IntPtr.Zero)) return false;
   630    632   
   631    633           bool result = false;
   632    634   

Changes to System.Data.SQLite/SQLiteConnection.cs.

   491    491         UnsafeNativeMethods.Initialize();
   492    492   #endif
   493    493   
   494    494   #if !INTEROP_LOG
   495    495         SQLiteLog.Initialize();
   496    496   #endif
   497    497   
   498         -#if !PLATFORM_COMPACTFRAMEWORK && SQLITE_STANDARD
          498  +#if !PLATFORM_COMPACTFRAMEWORK && !INTEROP_LEGACY_CLOSE && SQLITE_STANDARD
   499    499         //
   500    500         // NOTE: Check if the sqlite3_close_v2() native API should be available
   501    501         //       to use.  This must be done dynamically because the delegate set
   502    502         //       here is used by the SQLiteConnectionHandle class, which is a
   503    503         //       CriticalHandle derived class (i.e. protected by a constrained
   504    504         //       execution region).  Therefore, if the underlying native entry
   505    505         //       point is unavailable, an exception will be raised even if it is

Changes to System.Data.SQLite/SQLiteDefineConstants.cs.

    31     31   #if INTEROP_DEBUG
    32     32               "INTEROP_DEBUG",
    33     33   #endif
    34     34   
    35     35   #if INTEROP_EXTENSION_FUNCTIONS
    36     36               "INTEROP_EXTENSION_FUNCTIONS",
    37     37   #endif
           38  +
           39  +#if INTEROP_LEGACY_CLOSE
           40  +            "INTEROP_LEGACY_CLOSE",
           41  +#endif
    38     42   
    39     43   #if INTEROP_LOG
    40     44               "INTEROP_LOG",
    41     45   #endif
    42     46   
    43     47   #if INTEROP_TEST_EXTENSION
    44     48               "INTEROP_TEST_EXTENSION",

Changes to System.Data.SQLite/System.Data.SQLite.Properties.targets.

   149    149         NOTE: Enable extra diagnostics from the custom built interop DLL (see the
   150    150               "SQLite.NET.Settings.targets" file for more information)?
   151    151     -->
   152    152     <PropertyGroup Condition="'$(InteropDebug)' != 'false'">
   153    153       <DefineConstants>$(DefineConstants);INTEROP_DEBUG</DefineConstants>
   154    154     </PropertyGroup>
   155    155   
          156  +  <!--
          157  +      NOTE: Disable all use of the sqlite3_close_v2() native API and use the
          158  +            legacy System.Data.SQLite connection closing algorithm instead.
          159  +  -->
          160  +  <PropertyGroup Condition="'$(InteropLegacyClose)' != 'false'">
          161  +    <DefineConstants>$(DefineConstants);INTEROP_LEGACY_CLOSE</DefineConstants>
          162  +  </PropertyGroup>
          163  +
   156    164     <!--
   157    165         NOTE: Enable the logging callback in the custom built interop DLL (see
   158    166               the "SQLite.NET.Settings.targets" file for more information)?
   159    167     -->
   160    168     <PropertyGroup Condition="'$(InteropLog)' != 'false'">
   161    169       <DefineConstants>$(DefineConstants);INTEROP_LOG</DefineConstants>
   162    170     </PropertyGroup>

Changes to System.Data.SQLite/UnsafeNativeMethods.cs.

   639    639   #if !PLATFORM_COMPACTFRAMEWORK
   640    640       [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
   641    641   #else
   642    642       [DllImport(SQLITE_DLL)]
   643    643   #endif
   644    644       internal static extern SQLiteErrorCode sqlite3_close(IntPtr db);
   645    645   
          646  +#if !INTEROP_LEGACY_CLOSE
   646    647   #if !PLATFORM_COMPACTFRAMEWORK
   647    648       [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
   648    649   #else
   649    650       [DllImport(SQLITE_DLL)]
   650    651   #endif
   651    652       internal static extern SQLiteErrorCode sqlite3_close_v2(IntPtr db); /* 3.7.14+ */
          653  +#endif
   652    654   
   653    655   #if !PLATFORM_COMPACTFRAMEWORK
   654    656       [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
   655    657   #else
   656    658       [DllImport(SQLITE_DLL)]
   657    659   #endif
   658    660       internal static extern SQLiteErrorCode sqlite3_create_function(IntPtr db, byte[] strName, int nArgs, int nType, IntPtr pvUser, SQLiteCallback func, SQLiteCallback fstep, SQLiteFinalCallback ffinal);