Index: System.Data.SQLite/UnsafeNativeMethods.cs ================================================================== --- System.Data.SQLite/UnsafeNativeMethods.cs +++ System.Data.SQLite/UnsafeNativeMethods.cs @@ -1441,293 +1441,460 @@ } #endif - // Handles the unmanaged database pointer, and provides finalization support for it. - internal class SQLiteConnectionHandle : CriticalHandle - { - public static implicit operator IntPtr(SQLiteConnectionHandle db) - { - return (db != null) ? db.handle : IntPtr.Zero; - } - - internal SQLiteConnectionHandle(IntPtr db) - : this() - { - SetHandle(db); - } - - private SQLiteConnectionHandle() - : base(IntPtr.Zero) - { - } - - protected override bool ReleaseHandle() - { - try - { -#if !PLATFORM_COMPACTFRAMEWORK - IntPtr localHandle = Interlocked.Exchange( - ref handle, IntPtr.Zero); - - if (localHandle != IntPtr.Zero) - SQLiteBase.CloseConnection(this, localHandle); - -#if !NET_COMPACT_20 && TRACE_HANDLE - 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 - } -#if !NET_COMPACT_20 && TRACE_HANDLE - catch (SQLiteException e) -#else - catch (SQLiteException) -#endif - { -#if !NET_COMPACT_20 && TRACE_HANDLE - try - { - Trace.WriteLine(String.Format( - "CloseConnection: {0}, exception: {1}", - handle, e)); - } - catch - { - } -#endif - } - finally - { - SetHandleAsInvalid(); - } -#if DEBUG - return false; -#else - return true; -#endif - } - - public override bool IsInvalid - { - get { return (handle == IntPtr.Zero); } - } - -#if DEBUG - public override string ToString() - { - return handle.ToString(); - } -#endif - } - - // Provides finalization support for unmanaged SQLite statements. - internal class SQLiteStatementHandle : CriticalHandle - { - private SQLiteConnectionHandle cnn; - - public static implicit operator IntPtr(SQLiteStatementHandle stmt) - { - return (stmt != null) ? stmt.handle : IntPtr.Zero; - } - - internal SQLiteStatementHandle(SQLiteConnectionHandle cnn, IntPtr stmt) - : this() - { - this.cnn = cnn; - SetHandle(stmt); - } - - private SQLiteStatementHandle() - : base(IntPtr.Zero) - { - } - - protected override bool ReleaseHandle() - { - try - { -#if !PLATFORM_COMPACTFRAMEWORK - IntPtr localHandle = Interlocked.Exchange( - ref handle, IntPtr.Zero); - - if (localHandle != IntPtr.Zero) - SQLiteBase.FinalizeStatement(cnn, localHandle); - -#if !NET_COMPACT_20 && TRACE_HANDLE - try - { - Trace.WriteLine(String.Format( - "FinalizeStatement: {0}", localHandle)); - } - catch - { - } -#endif -#else - if (handle != IntPtr.Zero) - { - SQLiteBase.FinalizeStatement(cnn, handle); - SetHandle(IntPtr.Zero); - } -#endif - -#if DEBUG - return true; -#endif - } -#if !NET_COMPACT_20 && TRACE_HANDLE - catch (SQLiteException e) -#else - catch (SQLiteException) -#endif - { -#if !NET_COMPACT_20 && TRACE_HANDLE - try - { - Trace.WriteLine(String.Format( - "FinalizeStatement: {0}, exception: {1}", - handle, e)); - } - catch - { - } -#endif - } - finally - { - SetHandleAsInvalid(); - } -#if DEBUG - return false; -#else - return true; -#endif - } - - public override bool IsInvalid - { - get { return (handle == IntPtr.Zero); } - } - -#if DEBUG - public override string ToString() - { - return handle.ToString(); - } -#endif - } - - // Provides finalization support for unmanaged SQLite backup objects. - internal class SQLiteBackupHandle : CriticalHandle - { - private SQLiteConnectionHandle cnn; - - public static implicit operator IntPtr(SQLiteBackupHandle backup) - { - return (backup != null) ? backup.handle : IntPtr.Zero; - } - - internal SQLiteBackupHandle(SQLiteConnectionHandle cnn, IntPtr backup) - : this() - { - this.cnn = cnn; - SetHandle(backup); - } - - private SQLiteBackupHandle() - : base(IntPtr.Zero) - { - } - - protected override bool ReleaseHandle() - { - try - { -#if !PLATFORM_COMPACTFRAMEWORK - IntPtr localHandle = Interlocked.Exchange( - ref handle, IntPtr.Zero); - - if (localHandle != IntPtr.Zero) - SQLiteBase.FinishBackup(cnn, localHandle); - -#if !NET_COMPACT_20 && TRACE_HANDLE - try - { - Trace.WriteLine(String.Format( - "FinishBackup: {0}", localHandle)); - } - catch - { - } -#endif -#else - if (handle != IntPtr.Zero) - { - SQLiteBase.FinishBackup(cnn, handle); - SetHandle(IntPtr.Zero); - } -#endif - -#if DEBUG - return true; -#endif - } -#if !NET_COMPACT_20 && TRACE_HANDLE - catch (SQLiteException e) -#else - catch (SQLiteException) -#endif - { -#if !NET_COMPACT_20 && TRACE_HANDLE - try - { - Trace.WriteLine(String.Format( - "FinishBackup: {0}, exception: {1}", - handle, e)); - } - catch - { - } -#endif - } - finally - { - SetHandleAsInvalid(); - } -#if DEBUG - return false; -#else - return true; -#endif - } - - public override bool IsInvalid - { - get { return (handle == IntPtr.Zero); } - } - -#if DEBUG - public override string ToString() - { - return handle.ToString(); - } -#endif - } + /////////////////////////////////////////////////////////////////////////// + + #region SQLiteConnectionHandle Class + // Handles the unmanaged database pointer, and provides finalization + // support for it. + internal class SQLiteConnectionHandle : CriticalHandle + { +#if PLATFORM_COMPACTFRAMEWORK + private readonly object syncRoot = new object(); +#endif + + /////////////////////////////////////////////////////////////////////// + + public static implicit operator IntPtr(SQLiteConnectionHandle db) + { + if (db != null) + { +#if PLATFORM_COMPACTFRAMEWORK + lock (db.syncRoot) +#endif + { + return db.handle; + } + } + return IntPtr.Zero; + } + + /////////////////////////////////////////////////////////////////////// + + internal SQLiteConnectionHandle(IntPtr db) + : this() + { +#if PLATFORM_COMPACTFRAMEWORK + lock (syncRoot) +#endif + { + SetHandle(db); + } + } + + /////////////////////////////////////////////////////////////////////// + + private SQLiteConnectionHandle() + : base(IntPtr.Zero) + { + } + + /////////////////////////////////////////////////////////////////////// + + protected override bool ReleaseHandle() + { + try + { +#if !PLATFORM_COMPACTFRAMEWORK + IntPtr localHandle = Interlocked.Exchange( + ref handle, IntPtr.Zero); + + if (localHandle != IntPtr.Zero) + SQLiteBase.CloseConnection(this, localHandle); + +#if !NET_COMPACT_20 && TRACE_HANDLE + try + { + Trace.WriteLine(String.Format( + "CloseConnection: {0}", localHandle)); + } + catch + { + } +#endif +#else + lock (syncRoot) + { + if (handle != IntPtr.Zero) + { + SQLiteBase.CloseConnection(this, handle); + SetHandle(IntPtr.Zero); + } + } +#endif +#if DEBUG + return true; +#endif + } +#if !NET_COMPACT_20 && TRACE_HANDLE + catch (SQLiteException e) +#else + catch (SQLiteException) +#endif + { +#if !NET_COMPACT_20 && TRACE_HANDLE + try + { + Trace.WriteLine(String.Format( + "CloseConnection: {0}, exception: {1}", + handle, e)); + } + catch + { + } +#endif + } + finally + { +#if PLATFORM_COMPACTFRAMEWORK + lock (syncRoot) +#endif + { + SetHandleAsInvalid(); + } + } +#if DEBUG + return false; +#else + return true; +#endif + } + + /////////////////////////////////////////////////////////////////////// + + public override bool IsInvalid + { + get + { +#if PLATFORM_COMPACTFRAMEWORK + lock (syncRoot) +#endif + { + return (handle == IntPtr.Zero); + } + } + } + + /////////////////////////////////////////////////////////////////////// + +#if DEBUG + public override string ToString() + { +#if PLATFORM_COMPACTFRAMEWORK + lock (syncRoot) +#endif + { + return handle.ToString(); + } + } +#endif + } + #endregion + + /////////////////////////////////////////////////////////////////////////// + + #region SQLiteStatementHandle Class + // Provides finalization support for unmanaged SQLite statements. + internal class SQLiteStatementHandle : CriticalHandle + { +#if PLATFORM_COMPACTFRAMEWORK + private readonly object syncRoot = new object(); +#endif + + /////////////////////////////////////////////////////////////////////// + + private SQLiteConnectionHandle cnn; + + /////////////////////////////////////////////////////////////////////// + + public static implicit operator IntPtr(SQLiteStatementHandle stmt) + { + if (stmt != null) + { +#if PLATFORM_COMPACTFRAMEWORK + lock (stmt.syncRoot) +#endif + { + return stmt.handle; + } + } + return IntPtr.Zero; + } + + /////////////////////////////////////////////////////////////////////// + + internal SQLiteStatementHandle(SQLiteConnectionHandle cnn, IntPtr stmt) + : this() + { +#if PLATFORM_COMPACTFRAMEWORK + lock (syncRoot) +#endif + { + this.cnn = cnn; + SetHandle(stmt); + } + } + + /////////////////////////////////////////////////////////////////////// + + private SQLiteStatementHandle() + : base(IntPtr.Zero) + { + } + + /////////////////////////////////////////////////////////////////////// + + protected override bool ReleaseHandle() + { + try + { +#if !PLATFORM_COMPACTFRAMEWORK + IntPtr localHandle = Interlocked.Exchange( + ref handle, IntPtr.Zero); + + if (localHandle != IntPtr.Zero) + SQLiteBase.FinalizeStatement(cnn, localHandle); + +#if !NET_COMPACT_20 && TRACE_HANDLE + try + { + Trace.WriteLine(String.Format( + "FinalizeStatement: {0}", localHandle)); + } + catch + { + } +#endif +#else + lock (syncRoot) + { + if (handle != IntPtr.Zero) + { + SQLiteBase.FinalizeStatement(cnn, handle); + SetHandle(IntPtr.Zero); + } + } +#endif +#if DEBUG + return true; +#endif + } +#if !NET_COMPACT_20 && TRACE_HANDLE + catch (SQLiteException e) +#else + catch (SQLiteException) +#endif + { +#if !NET_COMPACT_20 && TRACE_HANDLE + try + { + Trace.WriteLine(String.Format( + "FinalizeStatement: {0}, exception: {1}", + handle, e)); + } + catch + { + } +#endif + } + finally + { +#if PLATFORM_COMPACTFRAMEWORK + lock (syncRoot) +#endif + { + SetHandleAsInvalid(); + } + } +#if DEBUG + return false; +#else + return true; +#endif + } + + /////////////////////////////////////////////////////////////////////// + + public override bool IsInvalid + { + get + { +#if PLATFORM_COMPACTFRAMEWORK + lock (syncRoot) +#endif + { + return (handle == IntPtr.Zero); + } + } + } + + /////////////////////////////////////////////////////////////////////// + +#if DEBUG + public override string ToString() + { +#if PLATFORM_COMPACTFRAMEWORK + lock (syncRoot) +#endif + { + return handle.ToString(); + } + } +#endif + } + #endregion + + /////////////////////////////////////////////////////////////////////////// + + #region SQLiteBackupHandle Class + // Provides finalization support for unmanaged SQLite backup objects. + internal class SQLiteBackupHandle : CriticalHandle + { +#if PLATFORM_COMPACTFRAMEWORK + private readonly object syncRoot = new object(); +#endif + + /////////////////////////////////////////////////////////////////////// + + private SQLiteConnectionHandle cnn; + + /////////////////////////////////////////////////////////////////////// + + public static implicit operator IntPtr(SQLiteBackupHandle backup) + { + if (backup != null) + { +#if PLATFORM_COMPACTFRAMEWORK + lock (backup.syncRoot) +#endif + { + return backup.handle; + } + } + return IntPtr.Zero; + } + + /////////////////////////////////////////////////////////////////////// + + internal SQLiteBackupHandle(SQLiteConnectionHandle cnn, IntPtr backup) + : this() + { +#if PLATFORM_COMPACTFRAMEWORK + lock (syncRoot) +#endif + { + this.cnn = cnn; + SetHandle(backup); + } + } + + /////////////////////////////////////////////////////////////////////// + + private SQLiteBackupHandle() + : base(IntPtr.Zero) + { + } + + /////////////////////////////////////////////////////////////////////// + + protected override bool ReleaseHandle() + { + try + { +#if !PLATFORM_COMPACTFRAMEWORK + IntPtr localHandle = Interlocked.Exchange( + ref handle, IntPtr.Zero); + + if (localHandle != IntPtr.Zero) + SQLiteBase.FinishBackup(cnn, localHandle); + +#if !NET_COMPACT_20 && TRACE_HANDLE + try + { + Trace.WriteLine(String.Format( + "FinishBackup: {0}", localHandle)); + } + catch + { + } +#endif +#else + lock (syncRoot) + { + if (handle != IntPtr.Zero) + { + SQLiteBase.FinishBackup(cnn, handle); + SetHandle(IntPtr.Zero); + } + } +#endif +#if DEBUG + return true; +#endif + } +#if !NET_COMPACT_20 && TRACE_HANDLE + catch (SQLiteException e) +#else + catch (SQLiteException) +#endif + { +#if !NET_COMPACT_20 && TRACE_HANDLE + try + { + Trace.WriteLine(String.Format( + "FinishBackup: {0}, exception: {1}", + handle, e)); + } + catch + { + } +#endif + } + finally + { +#if PLATFORM_COMPACTFRAMEWORK + lock (syncRoot) +#endif + { + SetHandleAsInvalid(); + } + } +#if DEBUG + return false; +#else + return true; +#endif + } + + /////////////////////////////////////////////////////////////////////// + + public override bool IsInvalid + { + get + { +#if PLATFORM_COMPACTFRAMEWORK + lock (syncRoot) +#endif + { + return (handle == IntPtr.Zero); + } + } + } + + /////////////////////////////////////////////////////////////////////// + +#if DEBUG + public override string ToString() + { +#if PLATFORM_COMPACTFRAMEWORK + lock (syncRoot) +#endif + { + return handle.ToString(); + } + } +#endif + } + #endregion }