diff options
author | Alexander Köplinger <alex.koeplinger@outlook.com> | 2017-09-08 17:36:06 +0300 |
---|---|---|
committer | Marek Safar <marek.safar@gmail.com> | 2017-09-11 12:31:42 +0300 |
commit | 2d238eeb11ba7225e94651698d76c076b130f5c8 (patch) | |
tree | d3d268101371ee90c6aee51ebdd88d4413b4048b /mcs/class/System.Xaml | |
parent | f98d0799d89401853f59e4427764932d633b8935 (diff) |
[System.Xaml] Fix deadlock on exception in XamlBackgroundReader
The ManualResetEvent wouldn't be signaled when an exception happens
in the reader loop so we'd deadlock in Read().
I'm still investigating where the exception comes from but this
should at least help unblocking CI.
https://bugzilla.xamarin.com/show_bug.cgi?id=46683
Diffstat (limited to 'mcs/class/System.Xaml')
-rw-r--r-- | mcs/class/System.Xaml/System.Xaml/XamlBackgroundReader.cs | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/mcs/class/System.Xaml/System.Xaml/XamlBackgroundReader.cs b/mcs/class/System.Xaml/System.Xaml/XamlBackgroundReader.cs index 2859a14a9d9..d1d54491fd8 100644 --- a/mcs/class/System.Xaml/System.Xaml/XamlBackgroundReader.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlBackgroundReader.cs @@ -23,6 +23,7 @@ using System; using System.Collections.Generic; using System.Threading; +using System.Runtime.ExceptionServices; namespace System.Xaml { @@ -40,6 +41,7 @@ namespace System.Xaml XamlReader r; XamlNodeQueue q; bool read_all_done, do_work = true; + ExceptionDispatchInfo read_exception; ManualResetEvent wait = new ManualResetEvent (true); public bool HasLineInfo { @@ -92,6 +94,10 @@ namespace System.Xaml { if (q.IsEmpty) wait.WaitOne (); + + if (read_exception != null) + read_exception.Throw (); + return q.Reader.Read (); } @@ -105,11 +111,16 @@ namespace System.Xaml if (thread != null) throw new InvalidOperationException ("Thread has already started"); thread = new Thread (new ParameterizedThreadStart (delegate { - while (do_work && r.Read ()) { - q.Writer.WriteNode (r); + try { + while (do_work && r.Read ()) { + q.Writer.WriteNode (r); + wait.Set (); + } + read_all_done = true; + } catch (Exception ex) { + read_exception = ExceptionDispatchInfo.Capture (ex); wait.Set (); } - read_all_done = true; })) { Name = threadName }; thread.Start (); } |