Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Prevent the SQLiteLog.DomainUnload method from being added multiple times to the AppDomain.DomainUnload event, ticket [0d5b1ef362]. Stop trying to configure the SQLite logging interface in non-default AppDomains, ticket [ac47dd230a]. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
3054af47e2d8d92a8f9b22fabe23fd5e |
User & Date: | mistachkin 2011-10-04 08:05:22.820 |
References
2011-10-04
| ||
09:19 | • Ticket [ac47dd230a] Not Compatible with MSTest (concurrent App Domains) status still Closed with 2 other changes artifact: 8ead5f22bd user: mistachkin | |
08:10 | • Closed ticket [ac47dd230a]. artifact: 35e01feb19 user: mistachkin | |
08:06 | • Closed ticket [0d5b1ef362]: SQLiteLog.DomainUnload registered many times plus 4 other changes artifact: b809c056ec user: mistachkin | |
Context
2011-10-04
| ||
09:03 | The unit test infrastructure should make sure the native SQLite library is actually available. Also, update all version and release information for 1.0.76.0. check-in: 374035c537 user: mistachkin tags: trunk | |
08:05 | Prevent the SQLiteLog.DomainUnload method from being added multiple times to the AppDomain.DomainUnload event, ticket [0d5b1ef362]. Stop trying to configure the SQLite logging interface in non-default AppDomains, ticket [ac47dd230a]. check-in: 3054af47e2 user: mistachkin tags: trunk | |
2011-10-03
| ||
22:54 | Update downloads page for 1.0.75.0 release. check-in: fdf8786803 user: mistachkin tags: trunk, release | |
Changes
Changes to System.Data.SQLite/SQLiteLog.cs.
︙ | ︙ | |||
71 72 73 74 75 76 77 78 79 80 81 82 83 84 | { /// <summary> /// Object used to synchronize access to the static instance data /// for this class. /// </summary> private static object syncRoot = new object(); /// <summary> /// Member variable to store the application log handler to call. /// </summary> private static event SQLiteLogEventHandler _handlers; /// <summary> /// The default log event handler. | > > > > > | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | { /// <summary> /// Object used to synchronize access to the static instance data /// for this class. /// </summary> private static object syncRoot = new object(); /// <summary> /// Member variable to store the AppDomain.DomainUnload event handler. /// </summary> private static EventHandler _domainUnload; /// <summary> /// Member variable to store the application log handler to call. /// </summary> private static event SQLiteLogEventHandler _handlers; /// <summary> /// The default log event handler. |
︙ | ︙ | |||
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | private static bool _enabled; /// <summary> /// Initializes the SQLite logging facilities. /// </summary> public static void Initialize() { 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. // | > > > > > > > > > > > > > > > > > > > | > | > > | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | private static bool _enabled; /// <summary> /// Initializes the SQLite logging facilities. /// </summary> public static void Initialize() { // // 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); |
︙ | ︙ | |||
158 159 160 161 162 163 164 | /// <param name="sender"></param> /// <param name="e"></param> private static void DomainUnload( object sender, EventArgs e ) { | > > | | | | | | | | | | | | | | | > > > > > > > > > > > | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | /// <param name="sender"></param> /// <param name="e"></param> private static void DomainUnload( object sender, EventArgs e ) { lock (syncRoot) { // // BUGBUG: This will cause serious problems if other AppDomains // have any open SQLite connections; however, there is // currently no way around this limitation. // if (_sql != null) { int rc = _sql.Shutdown(); if (rc != 0) throw new SQLiteException(rc, "Failed to shutdown interface."); rc = _sql.SetLogCallback(null); if (rc != 0) throw new SQLiteException(rc, "Failed to shutdown logging."); } // // NOTE: Remove the event handler for the DomainUnload event // that we added earlier. // if (_domainUnload != null) { AppDomain.CurrentDomain.DomainUnload -= _domainUnload; _domainUnload = null; } } } /// <summary> /// This event is raised whenever SQLite raises a logging event. /// Note that this should be set as one of the first things in the /// application. |
︙ | ︙ |
Changes to Tests/common.eagle.
︙ | ︙ | |||
134 135 136 137 138 139 140 141 142 143 144 145 146 147 | return [info binary] } proc getBinaryFileName { fileName } { return [file nativename \ [file join [getBinaryDirectory] [file tail $fileName]]] } proc tryCopyBuildFile { fileName } { # # NOTE: If we cannot copy the assembly then it is probably already loaded. # set sourceFileName [getBuildFileName $fileName] | > > > > > > > > > > > > | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | return [info binary] } proc getBinaryFileName { fileName } { return [file nativename \ [file join [getBinaryDirectory] [file tail $fileName]]] } proc getAppDomainPreamble { {prefix ""} {suffix ""} } { return [uplevel 1 [list subst [appendArgs $prefix { if {[hasRuntimeOption native]} then { object invoke Interpreter.GetActive AddRuntimeOption native } set ::path {$::path} set ::test_year {[getBuildYear]} set ::test_configuration {[getBuildConfiguration]} } $suffix]]] } proc tryCopyBuildFile { fileName } { # # NOTE: If we cannot copy the assembly then it is probably already loaded. # set sourceFileName [getBuildFileName $fileName] |
︙ | ︙ |
Added Tests/tkt-0d5b1ef362.eagle.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | ############################################################################### # # tkt-0d5b1ef362.eagle -- # # Written by Joe Mistachkin. # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle package require EagleLibrary package require EagleTest runTestPrologue ############################################################################### package require System.Data.SQLite.Test runSQLiteTestPrologue ############################################################################### # # HACK: This test reads the private "_domainUnload" field of the AppDomain # class. This is non-portable and will not work on Mono. Also, this # may not work on versions of the .NET Framework after 4.0. # runTest {test tkt-0d5b1ef362-1.1 {SQLiteLog.DomainUnload event} -setup \ [getAppDomainPreamble] -body { # # NOTE: Grab the number of DomainUnload handlers prior to doing anything # else. # set x [object invoke -flags +NonPublic \ AppDomain.CurrentDomain._domainUnload.GetInvocationList Length] package require EagleLibrary package require EagleTest package require System.Data.SQLite.Test object load -loadtype File [file join [getBinaryDirectory] \ System.Data.SQLite.dll] for {set i 1} {$i < 3} {incr i} { set connection($i) [object create System.Data.SQLite.SQLiteConnection ""] } # # NOTE: Now, grab the number of DomainUnload handlers after creating the # connections. # set y [object invoke -flags +NonPublic \ AppDomain.CurrentDomain._domainUnload.GetInvocationList Length] # # NOTE: Make sure that no DomainUnload handlers were actually added while we # created the two connections (i.e. because we are not in the default # application domain). # expr {$x == $y} } -cleanup { unset -nocomplain connection i x y } -constraints {eagle dotNet monoBug28 command.sql compile.DATA\ compile.ISOLATED_INTERPRETERS System.Data.SQLite} -isolationLevel AppDomain \ -result {True}} ############################################################################### runSQLiteTestEpilogue runTestEpilogue |
Added Tests/tkt-ac47dd230a.eagle.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | ############################################################################### # # tkt-ac47dd230a.eagle -- # # Written by Joe Mistachkin. # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle package require EagleLibrary package require EagleTest runTestPrologue ############################################################################### package require System.Data.SQLite.Test runSQLiteTestPrologue ############################################################################### runTest {test tkt-ac47dd230a-1.1 {multiple AppDomains} -setup { for {set i 1} {$i < 3} {incr i} { set appDomain($i) [object invoke AppDomain CreateDomain \ tkt-ac47dd230a-1.1.$i] set result null set interpreterHelper($i) [object invoke -alias InterpreterHelper \ Create $appDomain($i) null Default null null null result] if {[string length $interpreterHelper($i)] == 0} then { error [object invoke $result ToString] } set interpreter($i) [$interpreterHelper($i) -alias Interpreter] set result null set code [$interpreter($i) EvaluateScript [getAppDomainPreamble] result] if {$code ne "Ok"} then { error [object invoke $result ToString] } } } -body { set results [list] for {set i 1} {$i < 3} {incr i} { set result null set code [$interpreter($i) EvaluateScript { package require EagleLibrary package require EagleTest package require System.Data.SQLite.Test object load -loadtype File [file join [getBinaryDirectory] \ System.Data.SQLite.dll] setupDb tkt-ac47dd230a-1.1; cleanupDb tkt-ac47dd230a-1.1 } result] lappend results $code [expr {[string length $result] > 0 ? \ [object invoke $result ToString] : ""}] } set results } -cleanup { unset -nocomplain results code result interpreter interpreterHelper for {set i 1} {$i < 3} {incr i} { object invoke AppDomain Unload $appDomain($i) } unset -nocomplain appDomain i } -constraints {eagle monoBug28 command.sql compile.DATA\ compile.ISOLATED_INTERPRETERS System.Data.SQLite} -result {Ok 0 Ok 0}} ############################################################################### runSQLiteTestEpilogue runTestEpilogue |
Changes to Tests/tkt-b4a7ddc83f.eagle.
︙ | ︙ | |||
26 27 28 29 30 31 32 | # object invoke -flags +NonPublic System.Data.SQLite.UnsafeNativeMethods \ sqlite3_shutdown ############################################################################### for {set i 1} {$i < 3} {incr i} { | | > < < < < < < < < | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | # object invoke -flags +NonPublic System.Data.SQLite.UnsafeNativeMethods \ sqlite3_shutdown ############################################################################### for {set i 1} {$i < 3} {incr i} { runTest {test tkt-b4a7ddc83f-1.$i {logging shutdown} -setup \ [getAppDomainPreamble { set appDomainId(1) {[object invoke AppDomain.CurrentDomain Id]} set fileName {tkt-b4a7ddc83f-1.$i.db} }] -body { set appDomainId(2) [object invoke AppDomain.CurrentDomain Id] package require EagleLibrary package require EagleTest package require System.Data.SQLite.Test |
︙ | ︙ |
Changes to test/TestCases.cs.
︙ | ︙ | |||
1619 1620 1621 1622 1623 1624 1625 | cnn.Open(); logevents = 0; cnn.LogMessage(1, "test log event"); if (logevents != 1) | | > | 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 | cnn.Open(); logevents = 0; cnn.LogMessage(1, "test log event"); if (logevents != 1) throw new Exception(String.Format( "Log event count {0} incorrect.", logevents)); cnn.Close(); // remove the log handler before the connection is closed. sqlite_fact.Log -= logHandler; } |
︙ | ︙ |
Changes to www/test.wiki.
︙ | ︙ | |||
107 108 109 110 111 112 113 | </li> <li> Make sure all tests pass; the log file "%TEMP%\EagleShell.exe.test.<pid>.log" may be checked if any errors should occur. EagleTest should produce "success" messages very similar to the following:<br /><br /> | | | | 107 108 109 110 111 112 113 114 115 116 117 118 119 | </li> <li> Make sure all tests pass; the log file "%TEMP%\EagleShell.exe.test.<pid>.log" may be checked if any errors should occur. EagleTest should produce "success" messages very similar to the following:<br /><br /> PASSED: 48<br /> TOTAL: 48<br /> PASS PERCENTAGE: 100%<br /> OVERALL RESULT: SUCCESS<br /> </li> </ol> |