Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix potential race condition between SQLiteBase.CloseConnection (via GC) and SQLiteBase.ResetConnection (via pool) when used on the same connection handle object. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | tkt-996d13cd87 |
Files: | files | file ages | folders |
SHA1: |
0ed439a5e7c51b6f95bc3e1461ad1f03 |
User & Date: | mistachkin 2012-04-30 17:17:26.330 |
Context
2012-04-30
| ||
17:18 | Remove superfluous using statement. check-in: b8fb8d4b6a user: mistachkin tags: tkt-996d13cd87 | |
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 | |
Changes
Changes to System.Data.SQLite/SQLite3.cs.
︙ | ︙ | |||
113 114 115 116 117 118 119 | // resources belonging to the previously-registered functions. internal override void Close() { if (_sql != null) { if (_usePool) { | | | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | // resources belonging to the previously-registered functions. internal override void Close() { if (_sql != null) { if (_usePool) { SQLiteBase.ResetConnection(_sql, _sql); SQLiteConnectionPool.Add(_fileName, _sql, _poolVersion); #if DEBUG && !NET_COMPACT_20 Trace.WriteLine(String.Format("Close (Pool): {0}", _sql)); #endif } else |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteBase.cs.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /******************************************************** * ADO.NET 2.0 Data Provider for SQLite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ namespace System.Data.SQLite { using System; /// <summary> /// This internal class provides the foundation of SQLite support. It defines all the abstract members needed to implement /// 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 { | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /******************************************************** * ADO.NET 2.0 Data Provider for SQLite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ namespace System.Data.SQLite { using System; using System.Threading; /// <summary> /// This internal class provides the foundation of SQLite support. It defines all the abstract members needed to implement /// 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 { |
︙ | ︙ | |||
369 370 371 372 373 374 375 | int n = UnsafeNativeMethods.sqlite3_finalize_interop(stmt); #else int n = UnsafeNativeMethods.sqlite3_finalize(stmt); #endif if (n > 0) throw new SQLiteException(n, null); } | | | > > | | | | | | > | | > > | | | | | | | | | | | | | | > | 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 | 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(SQLiteConnectionHandle hdl, IntPtr db) { if ((hdl == null) || (db == IntPtr.Zero)) return; lock (hdl) { #if !SQLITE_STANDARD int n = UnsafeNativeMethods.sqlite3_close_interop(db); #else ResetConnection(hdl, db); int n = UnsafeNativeMethods.sqlite3_close(db); #endif if (n > 0) throw new SQLiteException(n, SQLiteLastError(db)); } } internal static void ResetConnection(SQLiteConnectionHandle hdl, IntPtr db) { if ((hdl == null) || (db == IntPtr.Zero)) return; lock (hdl) { 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); |
︙ | ︙ |
Changes to System.Data.SQLite/UnsafeNativeMethods.cs.
︙ | ︙ | |||
1389 1390 1391 1392 1393 1394 1395 | try { #if !PLATFORM_COMPACTFRAMEWORK IntPtr localHandle = Interlocked.Exchange( ref handle, IntPtr.Zero); if (localHandle != IntPtr.Zero) | | | | 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 | try { #if !PLATFORM_COMPACTFRAMEWORK IntPtr localHandle = Interlocked.Exchange( ref handle, IntPtr.Zero); if (localHandle != IntPtr.Zero) SQLiteBase.CloseConnection(this, localHandle); #if DEBUG && !NET_COMPACT_20 try { Trace.WriteLine(String.Format( "CloseConnection: {0}", localHandle)); } catch { } #endif #else if (handle != IntPtr.Zero) { SQLiteBase.CloseConnection(this, handle); SetHandle(IntPtr.Zero); } #endif #if DEBUG return true; #endif |
︙ | ︙ |