// Gonzalo Paniagua Javier (gonzalo@ximian.com
//
// (C) 2002,2003 Ximian, Inc. (http://www.ximian.com)
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+using System;
+using System.Reflection;
using System.Runtime.CompilerServices;
+using System.Runtime.Remoting.Contexts;
+using System.Security.Permissions;
namespace System.Threading
{
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool WaitAll_internal(WaitHandle[] handles, int ms, bool exitContext);
- static void CheckArray (WaitHandle [] handles)
+ static void CheckArray (WaitHandle [] handles, bool waitAll)
{
if (handles == null)
throw new ArgumentNullException ("waitHandles");
if (length > 64)
throw new NotSupportedException ("Too many handles");
+ if (waitAll && length > 1 &&
+ (Thread.CurrentThread.ApartmentState == ApartmentState.STA ||
+ Assembly.GetEntryAssembly ().EntryPoint.GetCustomAttributes (typeof (STAThreadAttribute), false).Length == 1))
+ throw new NotSupportedException ("WaitAll for multiple handles is not allowed on an STA thread.");
+
foreach (WaitHandle w in handles) {
if (w == null)
throw new ArgumentNullException ("waitHandles", "null handle");
public static bool WaitAll(WaitHandle[] waitHandles)
{
- CheckArray (waitHandles);
+ CheckArray (waitHandles, true);
return(WaitAll_internal(waitHandles, Timeout.Infinite, false));
}
public static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
{
- CheckArray (waitHandles);
- return(WaitAll_internal(waitHandles, millisecondsTimeout, false));
+ CheckArray (waitHandles, true);
+ try {
+ if (exitContext) SynchronizationAttribute.ExitContext ();
+ return(WaitAll_internal(waitHandles, millisecondsTimeout, false));
+ }
+ finally {
+ if (exitContext) SynchronizationAttribute.EnterContext ();
+ }
}
public static bool WaitAll(WaitHandle[] waitHandles,
TimeSpan timeout,
bool exitContext)
{
- CheckArray (waitHandles);
+ CheckArray (waitHandles, true);
long ms = (long) timeout.TotalMilliseconds;
if (ms < -1 || ms > Int32.MaxValue)
throw new ArgumentOutOfRangeException ("timeout");
- return (WaitAll_internal (waitHandles, (int) ms, exitContext));
+ try {
+ if (exitContext) SynchronizationAttribute.ExitContext ();
+ return (WaitAll_internal (waitHandles, (int) ms, exitContext));
+ }
+ finally {
+ if (exitContext) SynchronizationAttribute.EnterContext ();
+ }
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
// LAMESPEC: Doesn't specify how to signal failures
public static int WaitAny(WaitHandle[] waitHandles)
{
- CheckArray (waitHandles);
+ CheckArray (waitHandles, false);
return(WaitAny_internal(waitHandles, Timeout.Infinite, false));
}
int millisecondsTimeout,
bool exitContext)
{
- CheckArray (waitHandles);
- return(WaitAny_internal(waitHandles, millisecondsTimeout, exitContext));
+ CheckArray (waitHandles, false);
+ try {
+ if (exitContext) SynchronizationAttribute.ExitContext ();
+ return(WaitAny_internal(waitHandles, millisecondsTimeout, exitContext));
+ }
+ finally {
+ if (exitContext) SynchronizationAttribute.EnterContext ();
+ }
}
public static int WaitAny(WaitHandle[] waitHandles,
TimeSpan timeout, bool exitContext)
{
- CheckArray (waitHandles);
+ CheckArray (waitHandles, false);
long ms = (long) timeout.TotalMilliseconds;
if (ms < -1 || ms > Int32.MaxValue)
throw new ArgumentOutOfRangeException ("timeout");
- return (WaitAny_internal(waitHandles, (int) ms, exitContext));
+ try {
+ if (exitContext) SynchronizationAttribute.ExitContext ();
+ return (WaitAny_internal(waitHandles, (int) ms, exitContext));
+ }
+ finally {
+ if (exitContext) SynchronizationAttribute.EnterContext ();
+ }
}
[MonoTODO]
public const int WaitTimeout = 258;
- private IntPtr os_handle = IntPtr.Zero;
+ private IntPtr os_handle = InvalidHandle;
public virtual IntPtr Handle {
get {
return(os_handle);
}
+ [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
+ [SecurityPermission (SecurityAction.InheritanceDemand, UnmanagedCode = true)]
set {
os_handle=value;
}
GC.SuppressFinalize (this);
}
- protected void CheckDisposed ()
+ internal void CheckDisposed ()
{
if (disposed || os_handle == InvalidHandle)
throw new ObjectDisposedException (GetType ().FullName);
public virtual bool WaitOne(int millisecondsTimeout, bool exitContext)
{
CheckDisposed ();
- return(WaitOne_internal(os_handle, millisecondsTimeout, exitContext));
+ try {
+ if (exitContext) SynchronizationAttribute.ExitContext ();
+ return(WaitOne_internal(os_handle, millisecondsTimeout, exitContext));
+ }
+ finally {
+ if (exitContext) SynchronizationAttribute.EnterContext ();
+ }
}
public virtual bool WaitOne(TimeSpan timeout, bool exitContext)
if (ms < -1 || ms > Int32.MaxValue)
throw new ArgumentOutOfRangeException ("timeout");
- return (WaitOne_internal(os_handle, (int) ms, exitContext));
+ try {
+ if (exitContext) SynchronizationAttribute.ExitContext ();
+ return (WaitOne_internal(os_handle, (int) ms, exitContext));
+ }
+ finally {
+ if (exitContext) SynchronizationAttribute.EnterContext ();
+ }
}
protected static readonly IntPtr InvalidHandle = IntPtr.Zero;
- private bool disposed = false;
+ bool disposed = false;
void IDisposable.Dispose() {
Dispose(true);