Remove Thread.[Abort|Suspend|Resume] from TvOS/WatchOS.
authorRolf Bjarne Kvinge <rolf@xamarin.com>
Tue, 6 Oct 2015 11:47:37 +0000 (13:47 +0200)
committerRolf Bjarne Kvinge <rolf@xamarin.com>
Thu, 19 Nov 2015 11:54:36 +0000 (12:54 +0100)
In tests replace usages of Thread.Abort with Thread.Interrupt when it looks
like it can work, otherwise just disable the complete test.

18 files changed:
external/referencesource
mcs/build/profiles/monotouch_tv.make
mcs/build/profiles/monotouch_watch.make
mcs/class/System.Web.Services/Makefile
mcs/class/System.Web.Services/Test/System.Web.Services.Protocols/SocketResponder.cs
mcs/class/System/Makefile
mcs/class/System/Test/System.Net/HttpListener2Test.cs
mcs/class/System/Test/System.Net/HttpWebRequestTest.cs
mcs/class/System/Test/System.Net/SocketResponder.cs
mcs/class/corlib/Makefile
mcs/class/corlib/System.Runtime.Remoting/RemotingServices.cs
mcs/class/corlib/System.Threading/Thread.cs
mcs/class/corlib/Test/System.Diagnostics/StackTraceTest.cs
mcs/class/corlib/Test/System.Reflection/MethodInfoTest.cs
mcs/class/corlib/Test/System.Threading/MutexTest.cs
mcs/class/corlib/Test/System.Threading/ThreadCas.cs
mcs/class/corlib/Test/System.Threading/ThreadTest.cs
mcs/mcs/eval.cs

index 8c73c45821dfbaf20fb303db1a73f8de96c0a515..ceb0582568062b7d96f3d98b65453a903fdfa6d2 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 8c73c45821dfbaf20fb303db1a73f8de96c0a515
+Subproject commit ceb0582568062b7d96f3d98b65453a903fdfa6d2
index b546e50c167aa20417d7cd6b1be9cc342890c34c..084af615caaa1c8545b7fe4c808c76cb929458f7 100644 (file)
@@ -2,3 +2,6 @@ include $(topdir)/build/profiles/monotouch.make
 
 PROFILE_MCS_FLAGS += \
        -d:MONOTOUCH_TV
+
+NO_THREAD_ABORT=1
+NO_THREAD_SUSPEND_RESUME=1
index eb2880175adf03f26a21f8325ec7dc188f79d43a..9a68dcf9eb59a795eae74630dde54523f33fc7cf 100644 (file)
@@ -2,3 +2,6 @@ include $(topdir)/build/profiles/monotouch.make
 
 PROFILE_MCS_FLAGS += \
        -d:MONOTOUCH_WATCH
+
+NO_THREAD_ABORT=1
+NO_THREAD_SUSPEND_RESUME=1
index 235ddbed880d4aefe7c448f122269888873eb586..c189f7963eb63425694f478679cdad6841ffab3d 100644 (file)
@@ -46,6 +46,14 @@ endif
 
 TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) -nowarn:618
 
+ifndef NO_THREAD_ABORT
+TEST_MCS_FLAGS += -d:MONO_FEATURE_THREAD_ABORT
+endif
+
+ifndef NO_THREAD_SUSPEND_RESUME
+TEST_MCS_FLAGS += -d:MONO_FEATURE_THREAD_SUSPEND_RESUME
+endif
+
 EXTRA_DISTFILES = \
        System.Web.Services.Description/web-reference.xsd       \
        System.Web.Services.Description/wsdl-1.1.xsd            \
index 0682fa9081475aa7905c0f2fa0f4e877b1278c3c..2ebe7cf7b8e838a94ebba4ca93b170e418cf76fb 100644 (file)
@@ -96,7 +96,11 @@ namespace MonoTests.System.Web.Services.Protocols
                                if (tcpListener != null) {
                                        tcpListener.Stop ();
                                        tcpListener = null;
+#if MONO_FEATURE_THREAD_ABORT
                                        listenThread.Abort ();
+#else
+                                       listenThread.Interrupt ();
+#endif
                                        listenThread.Join ();
                                        listenThread = null;
                                }
index 912ae83bd9dc263fd79b5c759e8d8a1352653336..aef9e5f2b468b068198384282d7672acd2bf369e 100644 (file)
@@ -26,6 +26,16 @@ REFERENCE_SOURCES_FLAGS = -d:FEATURE_PAL,SYSTEM_NAMESPACE,MONO,PLATFORM_UNIX
 LIB_MCS_FLAGS = -nowarn:618 -d:CONFIGURATION_2_0 $(REFERENCE_SOURCES_FLAGS) -unsafe $(RESOURCE_FILES:%=-resource:%)
 TEST_MCS_FLAGS += -r:System.Configuration
 
+ifndef NO_THREAD_ABORT
+REFERENCE_SOURCES_FLAGS += -d:MONO_FEATURE_THREAD_ABORT
+TEST_MCS_FLAGS += -d:MONO_FEATURE_THREAD_ABORT
+endif
+
+ifndef NO_THREAD_SUSPEND_RESUME
+REFERENCE_SOURCES_FLAGS += -d:MONO_FEATURE_THREAD_SUSPEND_RESUME
+TEST_MCS_FLAGS += -d:MONO_FEATURE_THREAD_SUSPEND_RESUME
+endif
+
 RESOURCE_STRINGS = ../../../external/referencesource/System/System.txt
 
 #
index ab2901624e48fbb2e754d53d046ceb1fdadd0f3d..6e459b9d07896f0cf07b83e37b9dfdd9d2848656 100644 (file)
@@ -341,7 +341,11 @@ namespace MonoTests.System.Net {
                        Thread thread = new Thread (ReadToEnd);
                        thread.Start ();
                        if (test_evt.WaitOne (3000, false) == false) {
+#if MONO_FEATURE_THREAD_ABORT
                                thread.Abort ();
+#else
+                               thread.Interrupt ();
+#endif
                                test_evt.Close ();
                                Assert.IsTrue (false, "Timed out");
                        }
index a44034f267578f4d21eb487ce042c5230fbbcebf..20ee8020a98793e2accd2cb40b813d8bc08b4e25 100644 (file)
@@ -1468,7 +1468,11 @@ namespace MonoTests.System.Net
                        Thread.Sleep (three_seconds_in_milliseconds * 3);
 
                        if (timeoutWorker.End == null) {
+#if MONO_FEATURE_THREAD_ABORT
                                thread.Abort ();
+#else
+                               thread.Interrupt ();
+#endif
                                Assert.Fail ("Thread finished after triple the timeout specified has passed");
                        }
 
index 98035f55db7b3217bb6a605f06813f295554a50e..daa183afa063a8eda52b943fb8ff8c5a7f4f3f5b 100644 (file)
@@ -105,7 +105,11 @@ namespace MonoTests.System.Net
                                        tcpListener = null;
                                        if (listenSocket != null)
                                                listenSocket.Close ();
+#if MONO_FEATURE_THREAD_ABORT
                                        listenThread.Abort ();
+#else
+                                       listenThread.Interrupt ();
+#endif
                                        listenThread.Join ();
                                        listenThread = null;
                                        Thread.Sleep (50);
index 89222691f7ea0b0e2f0c929ea801d8d41c1e87d5..1162bf54f786093cca6184fc168e7324459f3c18 100644 (file)
@@ -41,12 +41,22 @@ ifndef MOBILE_STATIC
 REFERENCE_SOURCES_FLAGS += -d:FEATURE_REMOTING,MONO_COM,FEATURE_COMINTEROP,FEATURE_ROLE_BASED_SECURITY
 endif
 
+ifndef NO_THREAD_ABORT
+REFERENCE_SOURCES_FLAGS += -d:MONO_FEATURE_THREAD_ABORT
+TEST_MCS_FLAGS += -d:MONO_FEATURE_THREAD_ABORT
+endif
+
+ifndef NO_THREAD_SUSPEND_RESUME
+REFERENCE_SOURCES_FLAGS += -d:MONO_FEATURE_THREAD_SUSPEND_RESUME
+TEST_MCS_FLAGS += -d:MONO_FEATURE_THREAD_SUSPEND_RESUME
+endif
+
 WARNING_ABOUT_DISABLED_WARNING=1635
 LOCAL_MCS_FLAGS = -unsafe -nostdlib -nowarn:612,618,$(WARNING_ABOUT_DISABLED_WARNING) -d:INSIDE_CORLIB,MONO_CULTURE_DATA -d:LIBC $(REFERENCE_SOURCES_FLAGS)
 DEFAULT_REFERENCES =
 
 # System.IO/DirectoryInfoTest.cs needs Mono.Posix
-TEST_MCS_FLAGS = -debug -nowarn:168,219,618,672 -unsafe -r:Mono.Posix.dll -r:System.Core.dll \
+TEST_MCS_FLAGS += -debug -nowarn:168,219,618,672 -unsafe -r:Mono.Posix.dll -r:System.Core.dll \
                                 -define:MONO_DATACONVERTER_STATIC_METHODS $(TEST_RESX_RESOURCES:%=-resource:%)
 
 EXTRA_DISTFILES = \
index c0015138cd35639c9a79dda46921f71ca1806a19..bc424ce5e2d7d40c6d6a12cc4aa88eec2f7eb76f 100644 (file)
@@ -819,7 +819,9 @@ namespace System.Runtime.Remoting
                                        }
                                        catch (Exception e) {
                                                if (e is ThreadAbortException) {
+#if MONO_FEATURE_THREAD_ABORT
                                                        Thread.ResetAbort ();
+#endif
                                                        retry = 5;
                                                        ex = e;
                                                }
@@ -840,7 +842,9 @@ namespace System.Runtime.Remoting
                        catch (Exception tex)
                        {
                                byte[] data = SerializeExceptionData (tex);
+#if MONO_FEATURE_THREAD_ABORT
                                Thread.ResetAbort ();
+#endif
                                return data;
                        }
                }
index 23d6bb7286bdb5c013db1a41fe64267a52e7ebd4..a2e3f5b685de58f6e2dec02ebb8b92511d5907b2 100644 (file)
@@ -461,6 +461,7 @@ namespace System.Threading {
                        }
                }
 
+#if MONO_FEATURE_THREAD_ABORT
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                private extern static void Abort_internal (InternalThread thread, object stateInfo);
 
@@ -488,6 +489,7 @@ namespace System.Threading {
                void ClearAbortReason ()
                {
                }
+#endif // MONO_FEATURE_THREAD_ABORT
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private extern static void SpinWait_nop ();
index f2665988d522a91068e6ee20178ed89ea405fc15..4aa89c03720cd1056826dd166d6c787b70eebc96 100644 (file)
@@ -142,6 +142,7 @@ namespace MonoTests.System.Diagnostics {
                        new StackTrace (t, true);
                }
 
+#if MONO_FEATURE_THREAD_SUSPEND_RESUME
                [Test]
                [Ignore ("Not supported in Mono")]
                public void StackTrace_Thread_Suspended ()
@@ -151,6 +152,7 @@ namespace MonoTests.System.Diagnostics {
                        t.Suspend ();
                        new StackTrace (t, true);
                }
+#endif
 
                [Test]
                public void FrameCount ()
index 3c6e3da2ffb6f74955c01a9e2cca04d2fdeaf55b..b8a9de2b3c59a7908974d880877fdf8d4bcd2fb3 100644 (file)
@@ -205,6 +205,7 @@ namespace MonoTests.System.Reflection
                        return (int*) 0;
                }
 
+#if MONO_FEATURE_THREAD_ABORT
                [Test] // bug #81538
                public void InvokeThreadAbort ()
                {
@@ -223,6 +224,7 @@ namespace MonoTests.System.Reflection
                {
                        Thread.CurrentThread.Abort ();
                }
+#endif
 
                [Test] // bug #76541
                public void ToStringByRef ()
index a4669029b8882302d67cc2953ce2e7eee89677c3..5149ece6900f034409ae09a0ef9558d292894388 100644 (file)
@@ -128,7 +128,11 @@ namespace MonoTests.System.Threading
                                TestUtil.WaitForNotAlive (thread1, "");\r
                                Assert.AreEqual (100, class1.marker);\r
                        } finally {\r
+#if MONO_FEATURE_THREAD_ABORT\r
                                thread1.Abort ();\r
+#else\r
+                               thread1.Interrupt ();\r
+#endif\r
                        }\r
                }\r
 \r
@@ -150,8 +154,13 @@ namespace MonoTests.System.Threading
                        \r
                                Assert.AreEqual (class2.id, class2.marker);\r
                        } finally {\r
+#if MONO_FEATURE_THREAD_ABORT\r
                                thread1.Abort ();\r
                                thread2.Abort ();\r
+#else\r
+                               thread1.Interrupt ();\r
+                               thread2.Interrupt ();\r
+#endif\r
                        }\r
                }\r
 \r
index 57c1ca4dea4bdc7abf4d170840a5496d554085ad..b222d5bcab1cb5aefca7d0d25cac02add0f63be3 100644 (file)
@@ -69,6 +69,7 @@ namespace MonoCasTests.System.Threading {
 
                // test Demand by denying the caller of the required privileges
 
+#if MONO_FEATURE_THREAD_ABORT
                [Test]
                [SecurityPermission (SecurityAction.Deny, ControlThread = true)]
                [ExpectedException (typeof (SecurityException))]
@@ -84,7 +85,8 @@ namespace MonoCasTests.System.Threading {
                {
                        Thread.CurrentThread.Abort (new object [0]);
                }
-
+#endif
+               
                [Test]
                [SecurityPermission (SecurityAction.Deny, ControlThread = true)]
                [ExpectedException (typeof (SecurityException))]
@@ -101,6 +103,7 @@ namespace MonoCasTests.System.Threading {
                        Thread.CurrentThread.Interrupt ();
                }
 
+#if MONO_FEATURE_THREAD_ABORT
                [Test]
                [SecurityPermission (SecurityAction.Deny, ControlThread = true)]
                [ExpectedException (typeof (SecurityException))]
@@ -108,7 +111,9 @@ namespace MonoCasTests.System.Threading {
                {
                        Thread.ResetAbort ();
                }
+#endif
 
+#if MONO_FEATURE_THREAD_SUSPEND_RESUME
                [Test]
                [SecurityPermission (SecurityAction.Deny, ControlThread = true)]
                [ExpectedException (typeof (SecurityException))]
@@ -124,6 +129,7 @@ namespace MonoCasTests.System.Threading {
                {
                        Thread.CurrentThread.Suspend ();
                }
+#endif
 
                // we use reflection to call Mutex as it's named constructors are protected by
                // a LinkDemand (which will be converted into full demand, i.e. a stack walk) 
index 39b303f4736cdae36d3286191c01224ad14d99b7..b49fba552fa06750c132fa5a1eb7738475e391da 100644 (file)
@@ -184,7 +184,11 @@ namespace MonoTests.System.Threading
                        {
                                sub_thread.Start();
                                Thread.Sleep (100);
+#if MONO_FEATURE_THREAD_ABORT
                                sub_thread.Abort();
+#else
+                               sub_thread.Interrupt ();
+#endif
                        }
                }
                
@@ -215,10 +219,18 @@ namespace MonoTests.System.Threading
                                thread2.Start();
                                TestUtil.WaitForAlive (thread2, "wait2");
                                T2ON = true;
+#if MONO_FEATURE_THREAD_ABORT
                                thread1.Abort();
+#else
+                               thread1.Interrupt ();
+#endif
                                TestUtil.WaitForNotAlive (thread1, "wait3");
                                T1ON = false;
+#if MONO_FEATURE_THREAD_ABORT
                                thread2.Abort();
+#else
+                               thread2.Interrupt ();
+#endif
                                TestUtil.WaitForNotAlive (thread2, "wait4");
                                T2ON = false;
                        }
@@ -328,7 +340,11 @@ namespace MonoTests.System.Threading
                        C2Test test1 = new C2Test();
                        Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
                        TestThread.Start();
+#if MONO_FEATURE_THREAD_ABORT
                        TestThread.Abort();
+#else
+                       TestThread.Interrupt ();
+#endif
                        try {
                                TestThread.Start();
                                Assert.Fail ("#2");
@@ -343,7 +359,11 @@ namespace MonoTests.System.Threading
                        }
                        bool started = (TestThread.ThreadState == ThreadState.Running);
                        Assert.AreEqual (started, test1.run, "#15 Thread Is not in the correct state: ");
+#if MONO_FEATURE_THREAD_ABORT
                        TestThread.Abort();
+#else
+                       TestThread.Interrupt ();
+#endif
                }
                }
 
@@ -359,7 +379,11 @@ namespace MonoTests.System.Threading
                        TestThread.Start();
                        TestUtil.WaitForAlive (TestThread, "wait5");
                        Assert.AreEqual (ApartmentState.MTA, TestThread.ApartmentState, "#2");
+#if MONO_FEATURE_THREAD_ABORT
                        TestThread.Abort();
+#else
+                       TestThread.Interrupt ();
+#endif
                }
 
                [Test]
@@ -378,10 +402,15 @@ namespace MonoTests.System.Threading
                                ThreadPriority before = TestThread.Priority;
                                Assert.AreEqual (before, after, "#41 Unexpected Priority Change: ");
                        } finally {
+#if MONO_FEATURE_THREAD_ABORT
                                TestThread.Abort();
+#else
+                               TestThread.Interrupt ();
+#endif
                        }
                }
 
+#if MONO_FEATURE_THREAD_ABORT
                [Test]
                [Category ("NotDotNet")] // on MS, Thread is still in AbortRequested state when Start is invoked
                public void AbortUnstarted ()
@@ -391,6 +420,7 @@ namespace MonoTests.System.Threading
                        th.Abort ();
                        th.Start ();
                }
+#endif
 
                [Test]
                [Category ("NotDotNet")] // on MS, ThreadState is immediately Stopped after Abort
@@ -405,7 +435,11 @@ namespace MonoTests.System.Threading
                                TestUtil.WaitForAliveOrStop (TestThread, "wait8");
                                Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#43 Incorrect Priority in Started thread: ");
                        } finally {
+#if MONO_FEATURE_THREAD_ABORT
                                TestThread.Abort();
+#else
+                               TestThread.Interrupt ();
+#endif
                        }
                        Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#44 Incorrect Priority in Aborted thread: ");
                }
@@ -430,7 +464,11 @@ namespace MonoTests.System.Threading
                                Assert.AreEqual (ThreadPriority.Highest, TestThread.Priority, "#45E Incorrect Priority:");
                        }
                        finally {
+#if MONO_FEATURE_THREAD_ABORT
                                TestThread.Abort();
+#else
+                               TestThread.Interrupt ();
+#endif
                        }
                }
 
@@ -458,7 +496,11 @@ namespace MonoTests.System.Threading
                                bool state = TestThread.IsBackground;
                                Assert.IsFalse (state, "#51 IsBackground not set at the default state: ");
                        } finally {
+#if MONO_FEATURE_THREAD_ABORT
                                TestThread.Abort();
+#else
+                               TestThread.Interrupt ();
+#endif
                        }
                }
 
@@ -471,7 +513,11 @@ namespace MonoTests.System.Threading
                        try {
                                TestThread.Start();
                        } finally {
+#if MONO_FEATURE_THREAD_ABORT
                                TestThread.Abort();
+#else
+                               TestThread.Interrupt ();
+#endif
                        }
                        
                        if (TestThread.IsAlive) {
@@ -500,7 +546,11 @@ namespace MonoTests.System.Threading
                                TestThread.Name = newname;
                                Assert.AreEqual (newname, TestThread.Name, "#62 Name not set when must be set: ");
                        } finally {
+#if MONO_FEATURE_THREAD_ABORT
                                TestThread.Abort();
+#else
+                               TestThread.Interrupt ();
+#endif
                        }
                }
 
@@ -562,7 +612,11 @@ namespace MonoTests.System.Threading
                                TestThread.Start();
                                TestUtil.WaitForAlive (TestThread, "wait11");
                        } finally {
+#if MONO_FEATURE_THREAD_ABORT
                                TestThread.Abort();
+#else
+                               TestThread.Interrupt ();
+#endif
                        }
                }
 
@@ -574,7 +628,11 @@ namespace MonoTests.System.Threading
                        try {
                                TestThread.Start();
                        } finally {
+#if MONO_FEATURE_THREAD_ABORT
                                TestThread.Abort();
+#else
+                               TestThread.Interrupt ();
+#endif
                        }
                }
 
@@ -590,8 +648,13 @@ namespace MonoTests.System.Threading
                                thread2.Start();
                                thread2.Join();
                        } finally {
+#if MONO_FEATURE_THREAD_ABORT
                                thread1.Abort();
                                thread2.Abort();
+#else
+                               thread1.Interrupt ();
+                               thread2.Interrupt ();
+#endif
                        }
                }
 
@@ -676,7 +739,11 @@ namespace MonoTests.System.Threading
                                Assert.IsTrue (TestThread.ThreadState == ThreadState.Running || (TestThread.ThreadState & ThreadState.Unstarted) != 0,
                                        "#102 Wrong Thread State: " + TestThread.ThreadState.ToString ());
                        } finally {
+#if MONO_FEATURE_THREAD_ABORT
                                TestThread.Abort();
+#else
+                               TestThread.Interrupt ();
+#endif
                        }
                        
                        TestUtil.WaitForNotAlive (TestThread, "wait12");
@@ -696,7 +763,11 @@ namespace MonoTests.System.Threading
                                t.Start ();
                                t.Join ();
                        } catch {
+#if MONO_FEATURE_THREAD_ABORT
                                t.Abort ();
+#else
+                               t.Interrupt ();
+#endif
                        }
                }
 
@@ -711,7 +782,11 @@ namespace MonoTests.System.Threading
                                t.Start ();
                                t.Join ();
                        } catch {
+#if MONO_FEATURE_THREAD_ABORT
                                t.Abort ();
+#else
+                               t.Interrupt ();
+#endif
                        }
                }
 
@@ -725,7 +800,11 @@ namespace MonoTests.System.Threading
                                t.Start ();
                                t.Join ();
                        } catch {
+#if MONO_FEATURE_THREAD_ABORT
                                t.Abort ();
+#else
+                               t.Interrupt ();
+#endif
                        }
                }
                
@@ -739,12 +818,17 @@ namespace MonoTests.System.Threading
                                t.Start ();
                                t.Join ();
                        } catch {
+#if MONO_FEATURE_THREAD_ABORT
                                t.Abort ();
+#else
+                               t.Interrupt ();
+#endif
                        }
                }
 
                int counter = 0;
 
+#if MONO_FEATURE_THREAD_SUSPEND_RESUME
                [Test]
                public void TestSuspend ()
                {
@@ -768,7 +852,9 @@ namespace MonoTests.System.Threading
                        TestUtil.WaitForNotAlive (t, "wait13");
                        CheckIsNotRunning ("t6", t);
                }
-
+#endif
+               
+#if MONO_FEATURE_THREAD_SUSPEND_RESUME && MONO_FEATURE_THREAD_ABORT
                [Test]
                [Category("NotDotNet")] // On MS, ThreadStateException is thrown on Abort: "Thread is suspended; attempting to abort"
                public void TestSuspendAbort ()
@@ -799,6 +885,7 @@ namespace MonoTests.System.Threading
                        
                        CheckIsNotRunning ("t6", t);
                }
+#endif
 
                [Test]
                public void Test_Interrupt ()
index 50f15489e3aa28e0678f420fd0aa15af0a9c37ae..62c02b1fd5602de8f4a01d5096f183472d3d2b9a 100644 (file)
@@ -192,8 +192,13 @@ namespace Mono.CSharp
                        if (!inited || !invoking)
                                return;
                        
-                       if (invoke_thread != null)
+                       if (invoke_thread != null) {
+#if MONO_FEATURE_THREAD_ABORT
                                invoke_thread.Abort ();
+#else
+                               invoke_thread.Interrupt ();
+#endif
+                       }
                }
 
                /// <summary>
@@ -367,9 +372,14 @@ namespace Mono.CSharp
                                invoke_thread = System.Threading.Thread.CurrentThread;
                                invoking = true;
                                compiled (ref retval);
+#if MONO_FEATURE_THREAD_ABORT
                        } catch (ThreadAbortException e){
                                Thread.ResetAbort ();
                                Console.WriteLine ("Interrupted!\n{0}", e);
+#else
+                       } catch (ThreadInterruptedException e) {
+                               Console.WriteLine ("Interrupted!\n{0}", e);
+#endif
                        } finally {
                                invoking = false;