System.Data.SQLite
Check-in [c593d21c60]
Not logged in

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

Overview
Comment:Remove superfluous lock from the static helper methods in the SQLiteBase class.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | tkt-996d13cd87
Files: files | file ages | folders
SHA1: c593d21c60bf11ab3eefdac13bc02fa1df3359a5
User & Date: mistachkin 2012-04-30 16:27:52
Context
2012-04-30
17:17
Fix potential race condition between SQLiteBase.CloseConnection (via GC) and SQLiteBase.ResetConnection (via pool) when used on the same connection handle object. check-in: 0ed439a5e7 user: mistachkin tags: tkt-996d13cd87
16:27
Remove superfluous lock from the static helper methods in the SQLiteBase class. check-in: c593d21c60 user: mistachkin tags: tkt-996d13cd87
2012-04-29
22:50
Add another sanity check before returning the connection handle stored via weak reference in the connection pool. check-in: 673dbbf177 user: mistachkin tags: tkt-996d13cd87
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

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

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
...
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
  /// a SQLite data provider, and inherits from SQLiteConvert which allows for simple translations of string to and from SQLite.
  /// </summary>
  internal abstract class SQLiteBase : SQLiteConvert, IDisposable
  {
    internal SQLiteBase(SQLiteDateFormats fmt, DateTimeKind kind)
      : base(fmt, kind) { }

    static internal object _lock = new object();

    /// <summary>
    /// Returns a string representing the active version of SQLite
    /// </summary>
    internal abstract string Version { get; }
    /// <summary>
    /// Returns the rowid of the most recent successful INSERT into the database from this connection.
    /// </summary>
................................................................................
      return UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg(db), -1);
#endif
    }

    internal static void FinishBackup(IntPtr backup)
    {
        if (backup == IntPtr.Zero) return;
        lock (_lock)
        {
            int n = UnsafeNativeMethods.sqlite3_backup_finish(backup);
            if (n > 0) throw new SQLiteException(n, null);
        }
    }

    internal static void FinalizeStatement(IntPtr stmt)
    {
      if (stmt == IntPtr.Zero) return;
      lock (_lock)
      {
#if !SQLITE_STANDARD
        int n = UnsafeNativeMethods.sqlite3_finalize_interop(stmt);
#else
        int n = UnsafeNativeMethods.sqlite3_finalize(stmt);
#endif
        if (n > 0) throw new SQLiteException(n, null);
      }
    }

    internal static void CloseConnection(IntPtr db)
    {
      if (db == IntPtr.Zero) return;
      lock (_lock)
      {
#if !SQLITE_STANDARD
        int n = UnsafeNativeMethods.sqlite3_close_interop(db);
#else
        ResetConnection(db);
        int n = UnsafeNativeMethods.sqlite3_close(db);
#endif
        if (n > 0) throw new SQLiteException(n, SQLiteLastError(db));
      }
    }

    internal static void ResetConnection(IntPtr db)
    {
      if (db == IntPtr.Zero) return;
      lock (_lock)
      {
        IntPtr stmt = IntPtr.Zero;
        int n;
        do
        {
          stmt = UnsafeNativeMethods.sqlite3_next_stmt(db, stmt);
          if (stmt != IntPtr.Zero)
          {
#if !SQLITE_STANDARD
            n = UnsafeNativeMethods.sqlite3_reset_interop(stmt);
#else
            n = UnsafeNativeMethods.sqlite3_reset(stmt);
#endif
          }
        } while (stmt != IntPtr.Zero);

        if (IsAutocommit(db) == false) // a transaction is pending on the connection
        {
          n = UnsafeNativeMethods.sqlite3_exec(db, ToUTF8("ROLLBACK"), IntPtr.Zero, IntPtr.Zero, out stmt);
          if (n > 0) throw new SQLiteException(n, SQLiteLastError(db));
        }
      }
    }

    internal static bool IsAutocommit(IntPtr db)
    {
      if (db == IntPtr.Zero) return false;
      return (UnsafeNativeMethods.sqlite3_get_autocommit(db) == 1);
    }







<
<







 







<
<
|
|
<




|
<
<






<




|
<
<







<




|
<
<




|
|
|

|

|

|




|
|

<







14
15
16
17
18
19
20


21
22
23
24
25
26
27
...
354
355
356
357
358
359
360


361
362

363
364
365
366
367


368
369
370
371
372
373

374
375
376
377
378


379
380
381
382
383
384
385

386
387
388
389
390


391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410

411
412
413
414
415
416
417
  /// a SQLite data provider, and inherits from SQLiteConvert which allows for simple translations of string to and from SQLite.
  /// </summary>
  internal abstract class SQLiteBase : SQLiteConvert, IDisposable
  {
    internal SQLiteBase(SQLiteDateFormats fmt, DateTimeKind kind)
      : base(fmt, kind) { }



    /// <summary>
    /// Returns a string representing the active version of SQLite
    /// </summary>
    internal abstract string Version { get; }
    /// <summary>
    /// Returns the rowid of the most recent successful INSERT into the database from this connection.
    /// </summary>
................................................................................
      return UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg(db), -1);
#endif
    }

    internal static void FinishBackup(IntPtr backup)
    {
        if (backup == IntPtr.Zero) return;


        int n = UnsafeNativeMethods.sqlite3_backup_finish(backup);
        if (n > 0) throw new SQLiteException(n, null);

    }

    internal static void FinalizeStatement(IntPtr stmt)
    {
        if (stmt == IntPtr.Zero) return;


#if !SQLITE_STANDARD
        int n = UnsafeNativeMethods.sqlite3_finalize_interop(stmt);
#else
        int n = UnsafeNativeMethods.sqlite3_finalize(stmt);
#endif
        if (n > 0) throw new SQLiteException(n, null);

    }

    internal static void CloseConnection(IntPtr db)
    {
        if (db == IntPtr.Zero) return;


#if !SQLITE_STANDARD
        int n = UnsafeNativeMethods.sqlite3_close_interop(db);
#else
        ResetConnection(db);
        int n = UnsafeNativeMethods.sqlite3_close(db);
#endif
        if (n > 0) throw new SQLiteException(n, SQLiteLastError(db));

    }

    internal static void ResetConnection(IntPtr db)
    {
        if (db == IntPtr.Zero) return;


        IntPtr stmt = IntPtr.Zero;
        int n;
        do
        {
            stmt = UnsafeNativeMethods.sqlite3_next_stmt(db, stmt);
            if (stmt != IntPtr.Zero)
            {
#if !SQLITE_STANDARD
                n = UnsafeNativeMethods.sqlite3_reset_interop(stmt);
#else
                n = UnsafeNativeMethods.sqlite3_reset(stmt);
#endif
            }
        } while (stmt != IntPtr.Zero);

        if (IsAutocommit(db) == false) // a transaction is pending on the connection
        {
            n = UnsafeNativeMethods.sqlite3_exec(db, ToUTF8("ROLLBACK"), IntPtr.Zero, IntPtr.Zero, out stmt);
            if (n > 0) throw new SQLiteException(n, SQLiteLastError(db));
        }

    }

    internal static bool IsAutocommit(IntPtr db)
    {
      if (db == IntPtr.Zero) return false;
      return (UnsafeNativeMethods.sqlite3_get_autocommit(db) == 1);
    }