System.Data.SQLite

Check-in [574f754156]
Login

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

Overview
Comment:Fix an issue that can occur during the disposal of a managed virtual table object instance.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 574f7541563babfd75111348415ecf74a5610218
User & Date: mistachkin 2013-08-05 21:52:08.964
Context
2013-08-07
03:51
When automatically registering custom functions, use the executing assembly (i.e. System.Data.SQLite) for reference detection. Fix for [4e49a58c4c]. check-in: 80a4ab671c user: mistachkin tags: trunk
2013-08-05
21:52
Fix an issue that can occur during the disposal of a managed virtual table object instance. check-in: 574f754156 user: mistachkin tags: trunk
2013-07-25
23:51
Project loading fix. Allow the SQLite.Interop projects for VS 2005/2008 to load without the INTEROP_EXTRA_PROPS_FILE environment variable being set. check-in: 311fc5a801 user: mistachkin tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to SQLite.Interop/src/ext/vtshim.c.
425
426
427
428
429
430
431

432
433
434
435
436
437
438

/* The destructor function for a disposible module */
static void vtshimAuxDestructor(void *pXAux){
  vtshim_aux *pAux = (vtshim_aux*)pXAux;
  assert( pAux->pAllVtab==0 );
  if( !pAux->bDisposed && pAux->xChildDestroy ){
    pAux->xChildDestroy(pAux->pChildAux);

  }
  sqlite3_free(pAux->zName);
  sqlite3_free(pAux->pMod);
  sqlite3_free(pAux);
}

static int vtshimCopyModule(







>







425
426
427
428
429
430
431
432
433
434
435
436
437
438
439

/* The destructor function for a disposible module */
static void vtshimAuxDestructor(void *pXAux){
  vtshim_aux *pAux = (vtshim_aux*)pXAux;
  assert( pAux->pAllVtab==0 );
  if( !pAux->bDisposed && pAux->xChildDestroy ){
    pAux->xChildDestroy(pAux->pChildAux);
    pAux->xChildDestroy = 0;
  }
  sqlite3_free(pAux->zName);
  sqlite3_free(pAux->pMod);
  sqlite3_free(pAux);
}

static int vtshimCopyModule(
523
524
525
526
527
528
529
530



531
532
533
534
535
536
537
    for(pVtab=pAux->pAllVtab; pVtab; pVtab=pVtab->pNext){
      for(pCur=pVtab->pAllCur; pCur; pCur=pCur->pNext){
        pAux->pMod->xClose(pCur->pChild);
      }
      pAux->pMod->xDisconnect(pVtab->pChild);
    }
    pAux->bDisposed = 1;
    if( pAux->xChildDestroy ) pAux->xChildDestroy(pAux->pChildAux);



  }
}


#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifdef _WIN32







|
>
>
>







524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
    for(pVtab=pAux->pAllVtab; pVtab; pVtab=pVtab->pNext){
      for(pCur=pVtab->pAllCur; pCur; pCur=pCur->pNext){
        pAux->pMod->xClose(pCur->pChild);
      }
      pAux->pMod->xDisconnect(pVtab->pChild);
    }
    pAux->bDisposed = 1;
    if( pAux->xChildDestroy ){
      pAux->xChildDestroy(pAux->pChildAux);
      pAux->xChildDestroy = 0;
    }
  }
}


#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifdef _WIN32
Changes to System.Data.SQLite/SQLiteModule.cs.
5344
5345
5346
5347
5348
5349
5350









5351
5352
5353
5354
5355
5356
5357
        /// This field is used to store the native sqlite3_module structure
        /// associated with this object instance.
        /// </summary>
        private UnsafeNativeMethods.sqlite3_module nativeModule;

        ///////////////////////////////////////////////////////////////////////










        /// <summary>
        /// This field is used to store a pointer to the native sqlite3_module
        /// structure returned by the sqlite3_create_disposable_module
        /// function.
        /// </summary>
        private IntPtr disposableModule;








>
>
>
>
>
>
>
>
>







5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
        /// This field is used to store the native sqlite3_module structure
        /// associated with this object instance.
        /// </summary>
        private UnsafeNativeMethods.sqlite3_module nativeModule;

        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// This field is used to store the destructor delegate to be passed to
        /// the SQLite core library via the sqlite3_create_disposable_module()
        /// function.
        /// </summary>
        private UnsafeNativeMethods.xDestroyModule destroyModule;

        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// This field is used to store a pointer to the native sqlite3_module
        /// structure returned by the sqlite3_create_disposable_module
        /// function.
        /// </summary>
        private IntPtr disposableModule;

5442
5443
5444
5445
5446
5447
5448



5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490



























5491
5492
5493
5494
5495
5496
5497
            try
            {
                pName = SQLiteString.Utf8IntPtrFromString(name);

                UnsafeNativeMethods.sqlite3_module nativeModule =
                    AllocateNativeModule();




#if !PLATFORM_COMPACTFRAMEWORK
                disposableModule =
                    UnsafeNativeMethods.sqlite3_create_disposable_module(
                        pDb, pName, ref nativeModule, IntPtr.Zero, null);

                return (disposableModule != IntPtr.Zero);
#elif !SQLITE_STANDARD
                disposableModule =
                    UnsafeNativeMethods.sqlite3_create_disposable_module_interop(
                       pDb, pName, AllocateNativeModuleInterop(),
                       nativeModule.iVersion, nativeModule.xCreate,
                       nativeModule.xConnect, nativeModule.xBestIndex,
                       nativeModule.xDisconnect, nativeModule.xDestroy,
                       nativeModule.xOpen, nativeModule.xClose,
                       nativeModule.xFilter, nativeModule.xNext,
                       nativeModule.xEof, nativeModule.xColumn,
                       nativeModule.xRowId, nativeModule.xUpdate,
                       nativeModule.xBegin, nativeModule.xSync,
                       nativeModule.xCommit, nativeModule.xRollback,
                       nativeModule.xFindFunction, nativeModule.xRename,
                       nativeModule.xSavepoint, nativeModule.xRelease,
                       nativeModule.xRollbackTo, IntPtr.Zero, null);

                return (disposableModule != IntPtr.Zero);
#else
                throw new NotImplementedException();
#endif
            }
            finally
            {
                if (pName != IntPtr.Zero)
                {
                    SQLiteMemory.Free(pName);
                    pName = IntPtr.Zero;
                }
            }
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Private Methods



























        /// <summary>
        /// Creates and returns the native sqlite_module structure using the
        /// configured (or default) <see cref="ISQLiteNativeModule" />
        /// interface implementation.
        /// </summary>
        /// <returns>
        /// The native sqlite_module structure using the configured (or







>
>
>



|

















|




















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
            try
            {
                pName = SQLiteString.Utf8IntPtrFromString(name);

                UnsafeNativeMethods.sqlite3_module nativeModule =
                    AllocateNativeModule();

                destroyModule = new UnsafeNativeMethods.xDestroyModule(
                    xDestroyModule);

#if !PLATFORM_COMPACTFRAMEWORK
                disposableModule =
                    UnsafeNativeMethods.sqlite3_create_disposable_module(
                        pDb, pName, ref nativeModule, IntPtr.Zero, destroyModule);

                return (disposableModule != IntPtr.Zero);
#elif !SQLITE_STANDARD
                disposableModule =
                    UnsafeNativeMethods.sqlite3_create_disposable_module_interop(
                       pDb, pName, AllocateNativeModuleInterop(),
                       nativeModule.iVersion, nativeModule.xCreate,
                       nativeModule.xConnect, nativeModule.xBestIndex,
                       nativeModule.xDisconnect, nativeModule.xDestroy,
                       nativeModule.xOpen, nativeModule.xClose,
                       nativeModule.xFilter, nativeModule.xNext,
                       nativeModule.xEof, nativeModule.xColumn,
                       nativeModule.xRowId, nativeModule.xUpdate,
                       nativeModule.xBegin, nativeModule.xSync,
                       nativeModule.xCommit, nativeModule.xRollback,
                       nativeModule.xFindFunction, nativeModule.xRename,
                       nativeModule.xSavepoint, nativeModule.xRelease,
                       nativeModule.xRollbackTo, IntPtr.Zero, destroyModule);

                return (disposableModule != IntPtr.Zero);
#else
                throw new NotImplementedException();
#endif
            }
            finally
            {
                if (pName != IntPtr.Zero)
                {
                    SQLiteMemory.Free(pName);
                    pName = IntPtr.Zero;
                }
            }
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Private Methods
        /// <summary>
        /// This method is called by the SQLite core library when the native
        /// module associated with this object instance is being destroyed due
        /// to its parent connection being closed.  It may also be called by
        /// the "vtshim" module if/when the sqlite3_dispose_module() function
        /// is called.
        /// </summary>
        /// <param name="pClientData">
        /// The native user-data pointer associated with this module, as it was
        /// provided to the SQLite core library when the native module instance
        /// was created.
        /// </param>
        private void xDestroyModule(
            IntPtr pClientData /* NOT USED */
            )
        {
            //
            // NOTE: At this point, just make sure that this native module
            //       handle is not reused, nor passed into the native
            //       sqlite3_dispose_module() function later (i.e. if/when
            //       the Dispose() method of this object instance is called).
            //
            disposableModule = IntPtr.Zero;
        }

        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Creates and returns the native sqlite_module structure using the
        /// configured (or default) <see cref="ISQLiteNativeModule" />
        /// interface implementation.
        /// </summary>
        /// <returns>
        /// The native sqlite_module structure using the configured (or