projects
/
mono.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge pull request #901 from Blewzman/FixAggregateExceptionGetBaseException
[mono.git]
/
mcs
/
class
/
corlib
/
System.Threading.Tasks
/
Task.cs
diff --git
a/mcs/class/corlib/System.Threading.Tasks/Task.cs
b/mcs/class/corlib/System.Threading.Tasks/Task.cs
index 1ae5559957ee710ce4206daf00fb0532f1df6987..bb023257b4769978f0db08de9d5a5a4a03119811 100644
(file)
--- a/
mcs/class/corlib/System.Threading.Tasks/Task.cs
+++ b/
mcs/class/corlib/System.Threading.Tasks/Task.cs
@@
-182,8
+182,11
@@
namespace System.Threading.Tasks
if (IsContinuation)
throw new InvalidOperationException ("Start may not be called on a continuation task");
if (IsContinuation)
throw new InvalidOperationException ("Start may not be called on a continuation task");
+ if (IsPromise)
+ throw new InvalidOperationException ("Start may not be called on a promise-style task");
+
SetupScheduler (scheduler);
SetupScheduler (scheduler);
- Schedule ();
+ Schedule (
true
);
}
internal void SetupScheduler (TaskScheduler scheduler)
}
internal void SetupScheduler (TaskScheduler scheduler)
@@
-208,10
+211,13
@@
namespace System.Threading.Tasks
if (IsContinuation)
throw new InvalidOperationException ("RunSynchronously may not be called on a continuation task");
if (IsContinuation)
throw new InvalidOperationException ("RunSynchronously may not be called on a continuation task");
- RunSynchronouslyCore (scheduler);
+ if (IsPromise)
+ throw new InvalidOperationException ("RunSynchronously may not be called on a promise-style task");
+
+ RunSynchronouslyCore (scheduler, true);
}
}
- internal void RunSynchronouslyCore (TaskScheduler scheduler)
+ internal void RunSynchronouslyCore (TaskScheduler scheduler
, bool throwException
)
{
SetupScheduler (scheduler);
Status = TaskStatus.WaitingToRun;
{
SetupScheduler (scheduler);
Status = TaskStatus.WaitingToRun;
@@
-220,11
+226,16
@@
namespace System.Threading.Tasks
if (scheduler.RunInline (this, false))
return;
} catch (Exception inner) {
if (scheduler.RunInline (this, false))
return;
} catch (Exception inner) {
- throw new TaskSchedulerException (inner);
+ var ex = new TaskSchedulerException (inner);
+ TrySetException (new AggregateException (ex), false, true);
+ if (throwException)
+ throw ex;
+
+ return;
}
}
- Schedule ();
- Wait
(
);
+ Schedule (
throwException
);
+ Wait
Core (Timeout.Infinite, CancellationToken.None, false
);
}
#endregion
}
#endregion
@@
-330,18
+341,27
@@
namespace System.Threading.Tasks
ContinueWith (new TaskContinuation (continuation, options));
}
ContinueWith (new TaskContinuation (continuation, options));
}
- internal
void ContinueWith (IContinuation continuation
)
+ internal
bool ContinueWith (IContinuation continuation, bool canExecuteInline = true
)
{
if (IsCompleted) {
{
if (IsCompleted) {
+ if (!canExecuteInline)
+ return false;
+
continuation.Execute ();
continuation.Execute ();
- return;
+ return
true
;
}
continuations.Add (continuation);
// Retry in case completion was achieved but event adding was too late
}
continuations.Add (continuation);
// Retry in case completion was achieved but event adding was too late
- if (IsCompleted && continuations.Remove (continuation))
+ if (IsCompleted && continuations.Remove (continuation)) {
+ if (!canExecuteInline)
+ return false;
+
continuation.Execute ();
continuation.Execute ();
+ }
+
+ return true;
}
internal void RemoveContinuation (IContinuation continuation)
}
internal void RemoveContinuation (IContinuation continuation)
@@
-364,10
+384,17
@@
namespace System.Threading.Tasks
#endregion
#region Internal and protected thingies
#endregion
#region Internal and protected thingies
- internal void Schedule ()
+ internal void Schedule (
bool throwException
)
{
Status = TaskStatus.WaitingToRun;
{
Status = TaskStatus.WaitingToRun;
- scheduler.QueueTask (this);
+ try {
+ scheduler.QueueTask (this);
+ } catch (Exception inner) {
+ var ex = new TaskSchedulerException (inner);
+ TrySetException (new AggregateException (ex), false, true);
+ if (throwException)
+ throw ex;
+ }
}
void ThreadStart ()
}
void ThreadStart ()
@@
-438,7
+465,7
@@
namespace System.Threading.Tasks
return true;
}
return true;
}
- internal bool TrySetException (AggregateException aggregate)
+ internal bool TrySetException (AggregateException aggregate
, bool cancellation, bool observed
)
{
if (IsCompleted)
return false;
{
if (IsCompleted)
return false;
@@
-450,8
+477,19
@@
namespace System.Threading.Tasks
return false;
}
return false;
}
-
- HandleGenericException (aggregate);
+
+ if (cancellation) {
+ ExceptionSlot.Exception = aggregate;
+ Thread.MemoryBarrier ();
+
+ CancelReal ();
+ } else {
+ HandleGenericException (aggregate);
+ }
+
+ if (observed)
+ exSlot.Observed = true;
+
return true;
}
return true;
}
@@
-641,7
+679,7
@@
namespace System.Threading.Tasks
if (millisecondsTimeout < -1)
throw new ArgumentOutOfRangeException ("millisecondsTimeout");
if (millisecondsTimeout < -1)
throw new ArgumentOutOfRangeException ("millisecondsTimeout");
- bool result = WaitCore (millisecondsTimeout, cancellationToken);
+ bool result = WaitCore (millisecondsTimeout, cancellationToken
, true
);
if (IsCanceled)
throw new AggregateException (new TaskCanceledException (this));
if (IsCanceled)
throw new AggregateException (new TaskCanceledException (this));
@@
-653,14
+691,19
@@
namespace System.Threading.Tasks
return result;
}
return result;
}
- internal bool WaitCore (int millisecondsTimeout, CancellationToken cancellationToken)
+ internal bool WaitCore (int millisecondsTimeout, CancellationToken cancellationToken
, bool runInline
)
{
if (IsCompleted)
return true;
// If the task is ready to be run and we were supposed to wait on it indefinitely without cancellation, just run it
{
if (IsCompleted)
return true;
// If the task is ready to be run and we were supposed to wait on it indefinitely without cancellation, just run it
- if (Status == TaskStatus.WaitingToRun && millisecondsTimeout == Timeout.Infinite && scheduler != null && !cancellationToken.CanBeCanceled)
- scheduler.RunInline (this, true);
+ if (runInline && Status == TaskStatus.WaitingToRun && millisecondsTimeout == Timeout.Infinite && scheduler != null && !cancellationToken.CanBeCanceled) {
+ try {
+ scheduler.RunInline (this, true);
+ } catch (Exception e) {
+ throw new TaskSchedulerException (e);
+ }
+ }
bool result = true;
bool result = true;
@@
-1082,6
+1125,9
@@
namespace System.Threading.Tasks
internal static Task<TResult[]> WhenAllCore<TResult> (IList<Task<TResult>> tasks)
{
internal static Task<TResult[]> WhenAllCore<TResult> (IList<Task<TResult>> tasks)
{
+ if (tasks.Count == 0)
+ return FromResult(new TResult[0]);
+
foreach (var t in tasks) {
if (t == null)
throw new ArgumentException ("tasks", "the tasks argument contains a null element");
foreach (var t in tasks) {
if (t == null)
throw new ArgumentException ("tasks", "the tasks argument contains a null element");
@@
-1242,7
+1288,7
@@
namespace System.Threading.Tasks
public AggregateException Exception {
get {
public AggregateException Exception {
get {
- if (exSlot == null)
+ if (exSlot == null
|| !IsFaulted
)
return null;
exSlot.Observed = true;
return exSlot.Exception;
return null;
exSlot.Observed = true;
return exSlot.Exception;
@@
-1283,7
+1329,7
@@
namespace System.Threading.Tasks
}
}
}
}
- TaskExceptionSlot ExceptionSlot {
+
internal
TaskExceptionSlot ExceptionSlot {
get {
if (exSlot != null)
return exSlot;
get {
if (exSlot != null)
return exSlot;
@@
-1328,6
+1374,12
@@
namespace System.Threading.Tasks
}
}
}
}
+ bool IsPromise {
+ get {
+ return invoker == TaskActionInvoker.Promise;
+ }
+ }
+
internal Task ContinuationAncestor {
get {
return contAncestor;
internal Task ContinuationAncestor {
get {
return contAncestor;