Skip to content

Commit

Permalink
[corlib] Mark all promise-style task exceptions observed. Fixes #17015
Browse files Browse the repository at this point in the history
  • Loading branch information
marek-safar committed Feb 3, 2014
1 parent 8c73578 commit b95d8a6
Show file tree
Hide file tree
Showing 8 changed files with 181 additions and 7 deletions.
Expand Up @@ -76,7 +76,7 @@ public static AsyncTaskMethodBuilder Create ()

public void SetException (Exception exception)
{
if (Task.TrySetException (new AggregateException (exception), exception is OperationCanceledException))
if (Task.TrySetException (new AggregateException (exception), exception is OperationCanceledException, true))
return;

throw new InvalidOperationException ("The task has already completed");
Expand Down
Expand Up @@ -76,7 +76,7 @@ public static AsyncTaskMethodBuilder<TResult> Create ()

public void SetException (Exception exception)
{
if (Task.TrySetException (new AggregateException (exception), exception is OperationCanceledException))
if (Task.TrySetException (new AggregateException (exception), exception is OperationCanceledException, true))
return;

throw new InvalidOperationException ("The task has already completed");
Expand Down
9 changes: 7 additions & 2 deletions mcs/class/corlib/System.Threading.Tasks/Task.cs
Expand Up @@ -226,7 +226,9 @@ internal void RunSynchronouslyCore (TaskScheduler scheduler)
if (scheduler.RunInline (this, false))
return;
} catch (Exception inner) {
throw new TaskSchedulerException (inner);
var ex = new TaskSchedulerException (inner);
TrySetException (new AggregateException (ex), false, true);
throw ex;
}

Schedule ();
Expand Down Expand Up @@ -454,7 +456,7 @@ internal bool TrySetCanceled ()
return true;
}

internal bool TrySetException (AggregateException aggregate, bool cancellation)
internal bool TrySetException (AggregateException aggregate, bool cancellation, bool observed)
{
if (IsCompleted)
return false;
Expand All @@ -476,6 +478,9 @@ internal bool TrySetException (AggregateException aggregate, bool cancellation)
HandleGenericException (aggregate);
}

if (observed)
exSlot.Observed = true;

return true;
}

Expand Down
Expand Up @@ -113,7 +113,7 @@ public bool TrySetException (IEnumerable<Exception> exceptions)
if (aggregate.InnerExceptions.Count == 0)
throw new ArgumentNullException ("exceptions");

return source.TrySetException (aggregate, false);
return source.TrySetException (aggregate, false, false);
}

public bool TrySetResult (TResult result)
Expand Down
4 changes: 2 additions & 2 deletions mcs/class/corlib/System.Threading.Tasks/TaskContinuation.cs
Expand Up @@ -202,7 +202,7 @@ public void Execute ()
}

if (exceptions != null) {
owner.TrySetException (new AggregateException (exceptions), false);
owner.TrySetException (new AggregateException (exceptions), false, false);
return;
}

Expand Down Expand Up @@ -262,7 +262,7 @@ public void Execute ()
}

if (exceptions != null) {
owner.TrySetException (new AggregateException (exceptions), false);
owner.TrySetException (new AggregateException (exceptions), false, false);
return;
}

Expand Down
17 changes: 17 additions & 0 deletions mcs/class/corlib/Test/System.Threading.Tasks/TaskTest.cs
Expand Up @@ -837,6 +837,23 @@ public void RunSynchronouslyArgumentChecks ()
}
}

[Test]
public void RunSynchronously_SchedulerException ()
{
var scheduler = new MockScheduler ();
scheduler.TryExecuteTaskInlineHandler += (task, b) => {
throw new ApplicationException ();
};

Task t = new Task (() => { });
try {
t.RunSynchronously (scheduler);
Assert.Fail ();
} catch (Exception e) {
Assert.AreEqual (t.Exception.InnerException, e);
}
}

[Test]
public void RunSynchronouslyWithAttachedChildren ()
{
Expand Down
46 changes: 46 additions & 0 deletions mcs/tests/test-async-59.cs
@@ -0,0 +1,46 @@
using System;
using System.Threading;
using System.Threading.Tasks;

class X
{
static bool unobserved;

public static int Main ()
{
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
try {
Test ().Wait ();

GC.Collect ();
GC.WaitForPendingFinalizers ();
if (unobserved)
return 1;

return 0;
} finally {
TaskScheduler.UnobservedTaskException -= TaskScheduler_UnobservedTaskException;
}
}

static void TaskScheduler_UnobservedTaskException (object sender, UnobservedTaskExceptionEventArgs e)
{
unobserved = true;
Console.WriteLine ("unobserved");
}

static async Task Test ()
{
try {
await ThrowAsync ();
} catch {
}
}

static async Task ThrowAsync()
{
await Task.Delay (5);

throw new Exception ("boom");
}
}
106 changes: 106 additions & 0 deletions mcs/tests/ver-il-net_4_5.xml
Expand Up @@ -60636,6 +60636,112 @@
</method>
</type>
</test>
<test name="test-async-56.cs">
<type name="Test">
<method name="Int32 Main()" attrs="150">
<size>70</size>
</method>
<method name="System.Threading.Tasks.Task`1[System.Int32] TestMethod()" attrs="145">
<size>33</size>
</method>
<method name="Void .ctor()" attrs="6278">
<size>7</size>
</method>
</type>
<type name="Test+&lt;TestMethod&gt;c__async0">
<method name="Void MoveNext()" attrs="486">
<size>169</size>
</method>
<method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
<size>13</size>
</method>
</type>
</test>
<test name="test-async-57.cs">
<type name="X">
<method name="Void Main()" attrs="150">
<size>2</size>
</method>
<method name="System.Threading.Tasks.Task TestAsync()" attrs="132">
<size>41</size>
</method>
<method name="Void .ctor()" attrs="6278">
<size>14</size>
</method>
</type>
<type name="X+&lt;TestAsync&gt;c__async0">
<method name="Void MoveNext()" attrs="486">
<size>172</size>
</method>
<method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
<size>13</size>
</method>
</type>
</test>
<test name="test-async-58.cs">
<type name="A">
<method name="Int32 Get()" attrs="134">
<size>10</size>
</method>
<method name="Void .ctor()" attrs="6278">
<size>7</size>
</method>
</type>
<type name="B">
<method name="System.Threading.Tasks.Task`1[System.Int32] GetAsync()" attrs="134">
<size>41</size>
</method>
<method name="Void Main()" attrs="145">
<size>17</size>
</method>
<method name="Void .ctor()" attrs="6278">
<size>7</size>
</method>
</type>
<type name="B+&lt;GetAsync&gt;c__async0">
<method name="Void MoveNext()" attrs="486">
<size>49</size>
</method>
<method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
<size>13</size>
</method>
</type>
</test>
<test name="test-async-59.cs">
<type name="X">
<method name="Int32 Main()" attrs="150">
<size>119</size>
</method>
<method name="Void TaskScheduler_UnobservedTaskException(System.Object, System.Threading.Tasks.UnobservedTaskExceptionEventArgs)" attrs="145">
<size>18</size>
</method>
<method name="System.Threading.Tasks.Task Test()" attrs="145">
<size>33</size>
</method>
<method name="System.Threading.Tasks.Task ThrowAsync()" attrs="145">
<size>33</size>
</method>
<method name="Void .ctor()" attrs="6278">
<size>7</size>
</method>
</type>
<type name="X+&lt;Test&gt;c__async0">
<method name="Void MoveNext()" attrs="486">
<size>190</size>
</method>
<method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
<size>13</size>
</method>
</type>
<type name="X+&lt;ThrowAsync&gt;c__async1">
<method name="Void MoveNext()" attrs="486">
<size>163</size>
</method>
<method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
<size>13</size>
</method>
</type>
</test>
<test name="test-cls-00.cs">
<type name="CLSCLass_6">
<method name="Void add_Disposed(Delegate)" attrs="2182">
Expand Down

0 comments on commit b95d8a6

Please sign in to comment.