Permalink
Browse files

Merge remote-tracking branch 'upstream/master'

* upstream/master: (21 commits)
  Add MaxHttpCollectionKey support
  44: Updated XML docs for IDependencyScope
  More Validation Performance Improvements
  Incorporate code review feedback for ResultConverters
  Issue 41: fix problem with Web API running in medium trust from the GAC
  Perf: improve conneg accept header sorting
  perf: Optimize return value validation of methods returning a non-generic Task. A direct comparison of the type to typeof(Task) is faster than analyzing if the type is generic or not.
  Code review feedback from bug #26
  Value Validation Performance Improvements
  Added copyright headers and License.txt
  Responding to customer and partner feedback re: the Anti-XSRF helpers.
  Performance improvements around simple parameters from the query string.  This gets about a 2x win in the case of calling get(int,int,int) in an in-memory loop.
  bug fix 395547: Addressing the issue that caused stress test failure on 4.5 where 401 response message sent is received as 500 error
  Remove IHttpControllerActivator.Release()
  Major TaskHelpers.Iterate perf wins. Create a fast-path for Task so that synchronous tasks execute immediately and we avoid any task allocations. This reduces iteration overhead to nearly 0. Remove iteration over Task<T> since nobody used it and it's slow.
  389622 - Escaping special characters in sections is not working
  Revert "257966: Parameterless overload of WebPage::ExecutePageHierarchy throws" Moving fix to next iteration.
  257966: Parameterless overload of WebPage::ExecutePageHierarchy throws when called.
  390625: Move the System.Web.Http.HttpRequestMessageExtensions and HttpResponseMessageExtensions classes to the System.Net.Http namespace
  Updating OAuth references in Microsoft.Web.WebPages.OAuth.Test to point to release version.
  ...

Conflicts:
	src/System.Json/Extensions/JsonValueExtensions.cs
	src/System.Json/JsonValueDynamicMetaObject.cs
  • Loading branch information...
2 parents f0242c6 + 22878f7 commit 1836deff6a2683b8a5b7dd78f2b591a10b47573e @grendello grendello committed Apr 16, 2012
Showing 2,339 changed files with 12,821 additions and 6,141 deletions.
View
@@ -0,0 +1,15 @@
+Copyright (c) Microsoft Corporation. All rights reserved.
+Microsoft would like to thank its contributors, a list of whom
+are at http://aspnetwebstack.codeplex.com/wikipage?title=Contributors.
+
+Licensed under the Apache License, Version 2.0 (the "License"); you
+may not use this file except in compliance with the License. You may
+obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+implied. See the License for the specific language governing permissions
+and limitations under the License.
@@ -1,4 +1,6 @@
-using System.Security;
+// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
+
+using System.Security;
//// REVIEW: RonCain -- This version is used by the WebStackRuntime assemblies that use types
//// from System.ComponentModelDataAnnotations which is not [SecurityTransparent]
@@ -1,3 +1,5 @@
+// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
+
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
View
@@ -1,3 +1,5 @@
+// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
+
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
@@ -1,4 +1,6 @@
-using System.Net.Http;
+// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
+
+using System.Net.Http;
namespace System.Web.Http
{
@@ -1,3 +1,5 @@
+// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
+
using System.Collections.Generic;
using System.Linq;
View
@@ -1,7 +1,8 @@
-using System.Collections.Generic;
+// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
-using System.Linq;
namespace System.Threading.Tasks
{
@@ -90,25 +91,82 @@ internal static Task<TResult> FromResult<TResult>(TResult result)
/// <param name="asyncIterator">collection of tasks to wait on</param>
/// <param name="cancellationToken">cancellation token</param>
/// <returns>a task that signals completed when all the incoming tasks are finished.</returns>
+ [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "The exception is propagated in a Task.")]
internal static Task Iterate(IEnumerable<Task> asyncIterator, CancellationToken cancellationToken = default(CancellationToken))
{
Contract.Assert(asyncIterator != null);
- return IterateEngine.Run(asyncIterator, cancellationToken);
+ IEnumerator<Task> enumerator = null;
+ try
+ {
+ enumerator = asyncIterator.GetEnumerator();
+ Task task = IterateImpl(enumerator, cancellationToken);
+ return (enumerator != null) ? task.Finally(enumerator.Dispose) : task;
+ }
+ catch (Exception ex)
+ {
+ return TaskHelpers.FromError(ex);
+ }
}
/// <summary>
- /// Return a task that runs all the tasks inside the iterator sequentially and collects the results.
- /// It stops as soon as one of the tasks fails or cancels, or after all the tasks have run succesfully.
+ /// Provides the implementation of the Iterate method.
+ /// Contains special logic to help speed up common cases.
/// </summary>
- /// <param name="asyncIterator">collection of tasks to wait on</param>
- /// <param name="cancellationToken">cancellation token</param>
- /// <returns>A task that, upon successful completion, returns the list of results.</returns>
- internal static Task<IEnumerable<TResult>> Iterate<TResult>(IEnumerable<Task<TResult>> asyncIterator, CancellationToken cancellationToken = default(CancellationToken))
+ [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "The exception is propagated in a Task.")]
+ internal static Task IterateImpl(IEnumerator<Task> enumerator, CancellationToken cancellationToken)
{
- Contract.Assert(asyncIterator != null);
+ try
+ {
+ while (true)
+ {
+ // short-circuit: iteration canceled
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return TaskHelpers.Canceled();
+ }
+
+ // short-circuit: iteration complete
+ if (!enumerator.MoveNext())
+ {
+ return TaskHelpers.Completed();
+ }
- return IterateEngine<TResult>.Run(asyncIterator, cancellationToken);
+ // fast case: Task completed synchronously & successfully
+ Task currentTask = enumerator.Current;
+ if (currentTask.Status == TaskStatus.RanToCompletion)
+ {
+ continue;
+ }
+
+ // fast case: Task completed synchronously & unsuccessfully
+ if (currentTask.IsCanceled || currentTask.IsFaulted)
+ {
+ return currentTask;
+ }
+
+ // slow case: Task isn't yet complete
+ return IterateImplIncompleteTask(enumerator, currentTask, cancellationToken);
+ }
+ }
+ catch (Exception ex)
+ {
+ return TaskHelpers.FromError(ex);
+ }
+ }
+
+ /// <summary>
+ /// Fallback for IterateImpl when the antecedent Task isn't yet complete.
+ /// </summary>
+ internal static Task IterateImplIncompleteTask(IEnumerator<Task> enumerator, Task currentTask, CancellationToken cancellationToken)
+ {
+ // There's a race condition here, the antecedent Task could complete between
+ // the check in Iterate and the call to Then below. If this happens, we could
+ // end up growing the stack indefinitely. But the chances of (a) even having
+ // enough Tasks in the enumerator in the first place and of (b) *every* one
+ // of them hitting this race condition are so extremely remote that it's not
+ // worth worrying about.
+ return currentTask.Then(() => IterateImpl(enumerator, cancellationToken));
}
/// <summary>
@@ -325,97 +383,5 @@ private static Task<TResult> GetCancelledTask()
return tcs.Task;
}
}
-
- // These classes are the engine that implements Iterate and Iterate<T>
- private static class IterateEngine
- {
- public static Task Run(IEnumerable<Task> iterator, CancellationToken cancellationToken)
- {
- // WARNING: This code uses LINQ Select to ensure that we get deferred execution (i.e., we
- // don't start running all the tasks all at once). If you touch this code, please ensure
- // that this behavior is preserved.
- return IterateEngine<AsyncVoid>.Run(iterator.Select(t => t.ToTask<AsyncVoid>()), cancellationToken);
- }
- }
-
- private class IterateEngine<TResult>
- {
- private CancellationToken _cancellationToken;
- private TaskCompletionSource<IEnumerable<TResult>> _completionSource;
- private IEnumerator<Task<TResult>> _enumerator;
- private List<TResult> _results;
- private SynchronizationContext _syncContext;
-
- public static Task<IEnumerable<TResult>> Run(IEnumerable<Task<TResult>> iterator, CancellationToken cancellationToken)
- {
- IterateEngine<TResult> engine = new IterateEngine<TResult>
- {
- _cancellationToken = cancellationToken,
- _completionSource = new TaskCompletionSource<IEnumerable<TResult>>(),
- _enumerator = iterator.GetEnumerator(),
- _results = new List<TResult>(),
- _syncContext = SynchronizationContext.Current
- };
-
- RunNext(engine);
- return engine._completionSource.Task.Finally(engine._enumerator.Dispose);
- }
-
- private static void RunNext(IterateEngine<TResult> engine)
- {
- if (engine._syncContext != null && engine._syncContext != SynchronizationContext.Current)
- {
- engine._syncContext.Post(RunNextCallback, engine);
- }
- else
- {
- RunNextCallback(engine);
- }
- }
-
- // TODO: This class can become more efficient once we take a hard 4.5 dependency. In 4.0, ContinueWith
- // does not offer you the ability to pass a state object; once it does, we can change the implementation
- // of RunNextCallback to remove the closure around "engine".
- [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "The caught exception type is reflected into a faulted task.")]
- [SuppressMessage("Microsoft.WebAPI", "CR4001:DoNotCallProblematicMethodsOnTask", Justification = "This usage is known to be safe.")]
- private static void RunNextCallback(object state)
- {
- IterateEngine<TResult> engine = (IterateEngine<TResult>)state;
-
- try
- {
- if (engine._cancellationToken.IsCancellationRequested)
- {
- engine._completionSource.TrySetCanceled();
- }
- else if (engine._enumerator.MoveNext())
- {
- engine._enumerator.Current.ContinueWith(previous =>
- {
- switch (previous.Status)
- {
- case TaskStatus.Faulted:
- case TaskStatus.Canceled:
- engine._completionSource.TrySetFromTask(previous);
- break;
-
- default:
- engine._results.Add(previous.Result);
- RunNext(engine);
- break;
- }
- }, TaskContinuationOptions.ExecuteSynchronously);
- }
- else
- {
- engine._completionSource.TrySetResult(engine._results);
- }
- }
- catch (Exception e)
- {
- engine._completionSource.TrySetException(e);
- }
- }
- }
}
}
@@ -1,4 +1,6 @@
-using System.Diagnostics.CodeAnalysis;
+// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
+
+using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using System.Linq.Expressions;
using System.Reflection;
@@ -46,7 +48,6 @@ internal static Task<TResult> Catch<TResult>(this Task<TResult> task, Func<Catch
{
return task;
}
-
return task.CatchImpl(() => continuation(new CatchInfo<TResult>(task)).Task, cancellationToken);
}
@@ -81,8 +82,9 @@ private static Task<TResult> CatchImpl<TResult>(this Task task, Func<Task<TResul
{
return TaskHelpers.Canceled<TResult>();
}
+
if (task.Status == TaskStatus.RanToCompletion)
- {
+ {
TaskCompletionSource<TResult> tcs = new TaskCompletionSource<TResult>();
tcs.TrySetFromTask(task);
return tcs.Task;
@@ -255,6 +257,7 @@ internal static Task Finally(this Task task, Action continuation)
}
catch (Exception ex)
{
+ MarkExceptionsObserved(task);
return TaskHelpers.FromError(ex);
}
}
@@ -280,6 +283,7 @@ internal static Task<TResult> Finally<TResult>(this Task<TResult> task, Action c
}
catch (Exception ex)
{
+ MarkExceptionsObserved(task);
return TaskHelpers.FromError<TResult>(ex);
}
}
@@ -308,14 +312,23 @@ private static Task<TResult> FinallyImplContinuation<TResult>(Task task, Action
}
catch (Exception ex)
{
+ MarkExceptionsObserved(innerTask);
tcs.SetException(ex);
}
}, state: null);
}
else
{
- continuation();
- tcs.TrySetFromTask(innerTask);
+ try
+ {
+ continuation();
+ tcs.TrySetFromTask(innerTask);
+ }
+ catch (Exception ex)
+ {
+ MarkExceptionsObserved(innerTask);
+ tcs.SetException(ex);
+ }
}
return tcs.Task;
@@ -381,6 +394,21 @@ private static Action<Task> GetRethrowWithNoStackLossDelegate()
}
/// <summary>
+ /// Marks a Task as "exception observed". The Task is required to have been completed first.
+ /// </summary>
+ /// <remarks>
+ /// Useful for 'finally' clauses, as if the 'finally' action throws we'll propagate the new
+ /// exception and lose track of the inner exception.
+ /// </remarks>
+ [SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "unused", Justification = "We only call the property getter for its side effect; we don't care about the value.")]
+ private static void MarkExceptionsObserved(this Task task)
+ {
+ Contract.Assert(task.IsCompleted);
+
+ Exception unused = task.Exception;
+ }
+
+ /// <summary>
/// Calls the given continuation, after the given task has completed, if the task successfully ran
/// to completion (i.e., was not cancelled and did not fault).
/// </summary>
@@ -1,4 +1,6 @@
-using System;
+// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
+
+using System;
using System.Reflection;
using System.Resources;
using System.Runtime.InteropServices;
View
@@ -1,3 +1,5 @@
+// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
+
using System;
using System.Collections.Generic;
using System.Diagnostics;
View
@@ -1,4 +1,6 @@
-using System;
+// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
+
+using System;
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.Internal.Web.Utils
@@ -1,3 +1,5 @@
+// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
+
using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames", Justification = "Assembly is delay-signed")]
View
@@ -1,3 +1,5 @@
+// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
+
using System.Collections;
namespace Microsoft.Internal.Web.Utils
@@ -1,4 +1,6 @@
-namespace Microsoft.Internal.Web.Utils
+// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
+
+namespace Microsoft.Internal.Web.Utils
{
internal interface IVirtualPathUtility
{
@@ -1,4 +1,6 @@
-using System.Diagnostics.CodeAnalysis;
+// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
+
+using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Scope = "member", Target = "Microsoft.Web.Helpers.Facebook.#GetInitializationScripts()", Justification = "It is analogous to the get pattern users are familiar with")]
[assembly: SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Scope = "member", Target = "Microsoft.Web.Helpers.Facebook.#GetFacebookUserProfile()", Justification = "It is analogous to the get pattern users are familiar with")]
@@ -1,4 +1,6 @@
-using System;
+// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
+
+using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
Oops, something went wrong.

0 comments on commit 1836def

Please sign in to comment.