/////////////////////////////////////////////////////////////////////// /// <summary> /// Initializes the SQLite logging facilities. /// </summary> /// <param name="className"> /// The name of the managed class that called this method. This /// parameter may be null. /// </param> internal static void Initialize( string className ) { // // NOTE: See if the logging subsystem has been totally disabled. // If so, do nothing. // if (UnsafeNativeMethods.GetSettingValue( "No_SQLiteLog", null) != null) { return; } /////////////////////////////////////////////////////////////// // // NOTE: Keep track of exactly how many times this method is // called (i.e. per-AppDomain, of course). // Interlocked.Increment(ref _initializeCallCount); /////////////////////////////////////////////////////////////// // // NOTE: First, check if the managed logging subsystem is always // supposed to at least attempt to initialize itself. In // order to do this, several fairly complex steps must be // taken, including calling a P/Invoke (interop) method; // therefore, by default, attempt to perform these steps // once. // if (UnsafeNativeMethods.GetSettingValue( "Initialize_SQLiteLog", null) == null) { if (Interlocked.Increment(ref _attemptedInitialize) > 1) { Interlocked.Decrement(ref _attemptedInitialize); return; } } /////////////////////////////////////////////////////////////////// // // BUFXIX: Cannot initialize the logging interface if the SQLite // core library has already been initialized anywhere in // the process (see ticket [2ce0870fad]). // if (SQLite3.StaticIsInitialized()) { return; } /////////////////////////////////////////////////////////////////// #if !PLATFORM_COMPACTFRAMEWORK // // BUGFIX: To avoid nasty situations where multiple AppDomains are // attempting to initialize and/or shutdown what is really // a shared native resource (i.e. the SQLite core library // is loaded per-process and has only one logging callback, // not one per-AppDomain, which it knows nothing about), // prevent all non-default AppDomains from registering a // log handler unless the "Force_SQLiteLog" environment // variable is used to manually override this safety check. // if (!AppDomain.CurrentDomain.IsDefaultAppDomain() && UnsafeNativeMethods.GetSettingValue("Force_SQLiteLog", null) == null) { return; } #endif /////////////////////////////////////////////////////////////////// lock (syncRoot) { #if !PLATFORM_COMPACTFRAMEWORK // // NOTE: Add an event handler for the DomainUnload event so // that we can unhook our logging managed function // pointer from the native SQLite code prior to it // being invalidated. // // BUGFIX: Make sure this event handler is only added one // time (per-AppDomain). // if (_domainUnload == null) { _domainUnload = new EventHandler(DomainUnload); AppDomain.CurrentDomain.DomainUnload += _domainUnload; } #endif /////////////////////////////////////////////////////////////// #if USE_INTEROP_DLL && INTEROP_LOG // // NOTE: Attempt to setup interop assembly log callback. // This may fail, e.g. if the SQLite core library // has somehow been initialized. An exception will // be raised in that case. // SQLiteErrorCode rc = SQLite3.ConfigureLogForInterop( className); if (rc != SQLiteErrorCode.Ok) { throw new SQLiteException(rc, "Failed to configure interop assembly logging."); } #else // // NOTE: Create an instance of the SQLite wrapper class. // if (_sql == null) { _sql = new SQLite3( SQLiteDateFormats.Default, DateTimeKind.Unspecified, null, IntPtr.Zero, null, false); } // // NOTE: Create a single "global" (i.e. per-process) callback // to register with SQLite. This callback will pass the // event on to any registered handler. We only want to // do this once. // if (_callback == null) { _callback = new SQLiteLogCallback(LogCallback); SQLiteErrorCode rc = _sql.SetLogCallback(_callback); if (rc != SQLiteErrorCode.Ok) { _callback = null; /* UNDO */ throw new SQLiteException(rc, "Failed to configure managed assembly logging."); } } #endif /////////////////////////////////////////////////////////////// // // NOTE: Logging is enabled by default unless the configuration // setting "Disable_SQLiteLog" is present. // if (UnsafeNativeMethods.GetSettingValue( "Disable_SQLiteLog", null) == null) { _enabled = true; } /////////////////////////////////////////////////////////////// // // NOTE: For now, always setup the default log event handler. // AddDefaultHandler(); } }
/// <summary> /// Initializes the SQLite logging facilities. /// </summary> public static void Initialize() { // // BUFXIX: We cannot initialize the logging interface if the SQLite // core library has already been initialized anywhere in // the process (see ticket [2ce0870fad]). // if (SQLite3.StaticIsInitialized()) { return; } // // BUGFIX: To avoid nasty situations where multiple AppDomains are // attempting to initialize and/or shutdown what is really // a shared native resource (i.e. the SQLite core library // is loaded per-process and has only one logging callback, // not one per-AppDomain, which it knows nothing about), // prevent all non-default AppDomains from registering a // log handler unless the "Force_SQLiteLog" environment // variable is used to manually override this safety check. // if (!AppDomain.CurrentDomain.IsDefaultAppDomain() && Environment.GetEnvironmentVariable("Force_SQLiteLog") == null) { return; } lock (syncRoot) { // // NOTE: Add an event handler for the DomainUnload event so // that we can unhook our logging managed function // pointer from the native SQLite code prior to it // being invalidated. // // BUGFIX: Make sure this event handler is only added one // time (per-AppDomain). // if (_domainUnload == null) { _domainUnload = new EventHandler(DomainUnload); AppDomain.CurrentDomain.DomainUnload += _domainUnload; } // // NOTE: Create an instance of the SQLite wrapper class. // if (_sql == null) { _sql = new SQLite3(SQLiteDateFormats.Default, DateTimeKind.Unspecified); } // // NOTE: Create a single "global" (i.e. per-process) callback // to register with SQLite. This callback will pass the // event on to any registered handler. We only want to // do this once. // if (_callback == null) { _callback = new SQLiteLogCallback(LogCallback); SQLiteErrorCode rc = _sql.SetLogCallback(_callback); if (rc != SQLiteErrorCode.Ok) { throw new SQLiteException(rc, "Failed to initialize logging."); } } // // NOTE: Logging is enabled by default. // _enabled = true; // // NOTE: For now, always setup the default log event handler. // AddDefaultHandler(); } }