예제 #1
0
        public virtual bool WaitOne()
        {
            CheckDisposed();
            bool release = false;

            try {
                safe_wait_handle.DangerousAddRef(ref release);
                return(WaitOne_internal(safe_wait_handle.DangerousGetHandle(), Timeout.Infinite, false));
            } finally {
                if (release)
                {
                    safe_wait_handle.DangerousRelease();
                }
            }
        }
예제 #2
0
        public const int TIME_OUT           = -2;                                         //Status definition : time out

        public AdvCANIO()
        {
            //
            // TODO: Add constructor logic here
            //
            String EventName;

            hDevice        = INVALID_HANDLE_VALUE;
            GCIoctl        = GCHandle.Alloc(ovIoctl, GCHandleType.Pinned);
            EventName      = "Ioctl" + hDevice.ToString();
            SafeWaitIoctl  = AdvCan.CreateEvent(0, false, false, EventName);
            ovIoctl.hEvent = SafeWaitIoctl.DangerousGetHandle();

            GCWrite        = GCHandle.Alloc(ovWrite, GCHandleType.Pinned);
            EventName      = "Write" + hDevice.ToString();
            SafeWaitWrite  = AdvCan.CreateEvent(0, false, false, EventName);
            ovWrite.hEvent = SafeWaitWrite.DangerousGetHandle();

            GCRead        = GCHandle.Alloc(ovRead, GCHandleType.Pinned);
            EventName     = "Read" + hDevice.ToString();
            SafeWaitRead  = AdvCan.CreateEvent(0, false, false, EventName);
            ovRead.hEvent = SafeWaitRead.DangerousGetHandle();

            GCEvent        = GCHandle.Alloc(ovEvent, GCHandleType.Pinned);
            EventName      = "Event" + hDevice.ToString();
            SafeWaitEvent  = AdvCan.CreateEvent(0, false, false, EventName);
            ovEvent.hEvent = SafeWaitEvent.DangerousGetHandle();

            lpCommandBuffer = Marshal.AllocHGlobal(AdvCan.CAN_COMMAND_LENGTH);
            lpConfigBuffer  = Marshal.AllocHGlobal(AdvCan.CAN_CONFIG_LENGTH);
            lpStatusBuffer  = Marshal.AllocHGlobal(AdvCan.CAN_CANSTATUS_LENGTH);
            lpEventCode     = Marshal.AllocHGlobal(Marshal.SizeOf(EventCode));
            Marshal.StructureToPtr(EventCode, lpEventCode, true);
        }
예제 #3
0
            public void Stop(bool callbackOnFinished)
            {
                lock (workerlock)
                {
                    if (workerrunning)
                    {
                        if (workerconnected)
                        {
                            clipboard.UnregisterClient();
                            workerconnected = false;
                        }
                        comms.CloseMessagePipes();

                        wmisession.Log("Stopping worker process " + worker.DangerousGetHandle().ToString());
                        registeredWorkerWaiter.Unregister(null);
                        try
                        {
                            // Don't kill the process.  If we have closed the Pipes, then that should be sufficient
                            // Win32Impl.KillProcess(worker.DangerousGetHandle(), 1);
                        }
                        catch
                        {
                            //If we fail to kill, we want to ignore this fact.  An error is already logged.
                        }
                        workerrunning = false;
                        if (callbackOnFinished)
                        {
                            wphandler.WorkerProcessFinished();
                        }
                    }
                }
            }
예제 #4
0
        public bool Unregister(WaitHandle waitObject)
        {
            // Hold the lock during the synchronous part of Unregister (as in CoreCLR)
            using (LockHolder.Hold(_lock))
            {
                if (!_unregistering)
                {
                    // Ensure callbacks will not call SetThreadpoolWait anymore
                    _unregistering = true;

                    // Cease queueing more callbacks
                    Interop.mincore.SetThreadpoolWait(_tpWait, IntPtr.Zero, IntPtr.Zero);

                    // Should we wait for callbacks synchronously? Note that we treat the zero handle as the asynchronous case.
                    SafeWaitHandle safeWaitHandle = waitObject?.SafeWaitHandle;
                    bool           blocking       = ((safeWaitHandle != null) && (safeWaitHandle.DangerousGetHandle() == Interop.InvalidHandleValue));

                    if (blocking)
                    {
                        FinishUnregistering();
                    }
                    else
                    {
                        // Wait for callbacks and dispose resources asynchronously
                        ThreadPool.QueueUserWorkItem(FinishUnregisteringAsync, safeWaitHandle);
                    }

                    return(true);
                }
            }
            return(false);
        }
예제 #5
0
        /// <summary>
        /// Signal <see cref="UserUnregisterWaitHandle"/> if it has not been signaled yet and is a valid handle.
        /// </summary>
        private void SignalUserWaitHandle()
        {
            _callbackLock.VerifyIsLocked();
            SafeWaitHandle handle      = UserUnregisterWaitHandle;
            IntPtr         handleValue = UserUnregisterWaitHandleValue;

            try
            {
                if (handleValue != IntPtr.Zero && handleValue != (IntPtr)(-1))
                {
                    Debug.Assert(handleValue == handle.DangerousGetHandle());
#if PLATFORM_WINDOWS
                    Interop.Kernel32.SetEvent(handle);
#else
                    WaitSubsystem.SetEvent(handleValue);
#endif
                }
            }
            finally
            {
                handle?.DangerousRelease();
                _callbacksComplete?.Set();
                _unregistered = true;
            }
        }
예제 #6
0
        internal static int TryMsgWaitForMultipleObjects(SafeWaitHandle handle, bool waitAll, int milliseconds, int wakeMask, ref int lastWin32Error)
        {
            int terminationEvent;

            if (handle == null)
            {
                terminationEvent = UnsafeNativeMethods.MsgWaitForMultipleObjects(0, null, waitAll, milliseconds, wakeMask);
                lastWin32Error   = Marshal.GetLastWin32Error();
            }
            else
            {
                bool fRelease = false;
                try
                {
                    handle.DangerousAddRef(ref fRelease);
                    IntPtr[] handles = { handle.DangerousGetHandle() };
                    terminationEvent = UnsafeNativeMethods.MsgWaitForMultipleObjects(1, handles, waitAll, milliseconds, wakeMask);
                    lastWin32Error   = Marshal.GetLastWin32Error();
                }
                finally
                {
                    if (fRelease)
                    {
                        handle.DangerousRelease();
                    }
                }
            }
            return(terminationEvent);
        }
예제 #7
0
        internal static int TryMsgWaitForMultipleObjects(SafeWaitHandle handle, bool waitAll, int milliseconds, int wakeMask, ref int lastWin32Error)
        {
            int terminationEvent;

            if (handle == null)
            {
                terminationEvent = UnsafeNativeMethods.MsgWaitForMultipleObjects(0, null, waitAll, milliseconds, wakeMask);
                lastWin32Error   = Marshal.GetLastWin32Error();
            }
            else
            {
                #pragma warning disable SYSLIB0004 // The Constrained Execution Region (CER) feature is not supported.
                RuntimeHelpers.PrepareConstrainedRegions();
                #pragma warning restore SYSLIB0004 // The Constrained Execution Region (CER) feature is not supported.
                bool fRelease = false;
                try
                {
                    handle.DangerousAddRef(ref fRelease);
                    IntPtr[] handles = { handle.DangerousGetHandle() };
                    terminationEvent = UnsafeNativeMethods.MsgWaitForMultipleObjects(1, handles, waitAll, milliseconds, wakeMask);
                    lastWin32Error   = Marshal.GetLastWin32Error();
                }
                finally
                {
                    if (fRelease)
                    {
                        handle.DangerousRelease();
                    }
                }
            }
            return(terminationEvent);
        }
예제 #8
0
        /// <summary>
        /// Obtains all of the corresponding safe wait handles and adds a ref to each. Since the <see cref="SafeWaitHandle"/>
        /// property is publically modifiable, this makes sure that we add and release refs one the same set of safe wait
        /// handles to keep them alive during a multi-wait operation.
        /// </summary>
        private static void ObtainSafeWaitHandles(
            ReadOnlySpan <WaitHandle> waitHandles,
            Span <SafeWaitHandle?> safeWaitHandles,
            Span <IntPtr> unsafeWaitHandles)
        {
            Debug.Assert(waitHandles != null);
            Debug.Assert(waitHandles.Length > 0);
            Debug.Assert(waitHandles.Length <= MaxWaitHandles);

            bool           lastSuccess        = true;
            SafeWaitHandle?lastSafeWaitHandle = null;

            try
            {
                for (int i = 0; i < waitHandles.Length; ++i)
                {
                    WaitHandle waitHandle = waitHandles[i];
                    if (waitHandle == null)
                    {
                        throw new ArgumentNullException("waitHandles[" + i + ']', SR.ArgumentNull_ArrayElement);
                    }

                    SafeWaitHandle safeWaitHandle = waitHandle._waitHandle ??
                                                    // Throw ObjectDisposedException for backward compatibility even though it is not representative of the issue
                                                    throw new ObjectDisposedException(null, SR.ObjectDisposed_Generic);

                    lastSafeWaitHandle = safeWaitHandle;
                    lastSuccess        = false;
                    safeWaitHandle.DangerousAddRef(ref lastSuccess);
                    safeWaitHandles[i]   = safeWaitHandle;
                    unsafeWaitHandles[i] = safeWaitHandle.DangerousGetHandle();
                }
            }
            catch
            {
                for (int i = 0; i < waitHandles.Length; ++i)
                {
                    SafeWaitHandle?safeWaitHandle = safeWaitHandles[i];
                    if (safeWaitHandle == null)
                    {
                        break;
                    }
                    safeWaitHandle.DangerousRelease();
                    safeWaitHandles[i] = null;
                    if (safeWaitHandle == lastSafeWaitHandle)
                    {
                        lastSafeWaitHandle = null;
                        lastSuccess        = true;
                    }
                }

                if (!lastSuccess)
                {
                    Debug.Assert(lastSafeWaitHandle != null);
                    lastSafeWaitHandle.DangerousRelease();
                }

                throw;
            }
        }
        public async Task SendAsync_WithCancellationToken_RequestResponseAndCancellationTokenCorrect()
        {
            var expectedRequestMessage = new HttpRequestMessage(HttpMethod.Get, "http://test.com");

            var expectedResponseMessage = new HttpResponseMessage(HttpStatusCode.OK);

            var expectedCancellationToken = new CancellationToken();

            HttpRequestMessage actualRequestMessage = null;
            SafeWaitHandle     actualCancellationTokenWaitHandle = null;

            var httpMessageHandler = new DelegateHttpMessageHandler((request, token) =>
            {
                actualRequestMessage = request;
                actualCancellationTokenWaitHandle = token.WaitHandle.SafeWaitHandle;
                return(Task.FromResult(expectedResponseMessage));
            });

            var httpClient = new HttpClient(httpMessageHandler);

            var response = await httpClient.SendAsync(expectedRequestMessage, expectedCancellationToken);

            Assert.Same(expectedRequestMessage, actualRequestMessage);
            Assert.True(expectedCancellationToken.WaitHandle.SafeWaitHandle.DangerousGetHandle()
                        .Equals(actualCancellationTokenWaitHandle.DangerousGetHandle()));
            Assert.Same(expectedResponseMessage, response);
        }
예제 #10
0
        internal static bool ResetEvent(SafeWaitHandle handle)
        {
            var acquiredLock = false;

            try
            {
                Monitor.Enter(handle, ref acquiredLock);

                unsafe
                {
                    var waitHandleData = (int *)handle.DangerousGetHandle().ToPointer();
                    if (waitHandleData == null)
                    {
                        throw new InvalidOperationException();
                    }

                    // state = false
                    waitHandleData[0] = 0;
                }
            }
            finally
            {
                if (acquiredLock)
                {
                    Monitor.Exit(handle);
                }
            }

            return(true);
        }
예제 #11
0
 public void Set()
 {
     if (SetEvent(SafeWaitHandle.DangerousGetHandle()) == false)
     {
         throw new Win32Exception();
     }
 }
예제 #12
0
        private bool WaitOneNoCheck(int millisecondsTimeout)
        {
            Debug.Assert(millisecondsTimeout >= -1);

            // The field value is modifiable via the public <see cref="WaitHandle.SafeWaitHandle"/> property, save it locally
            // to ensure that one instance is used in all places in this method
            SafeWaitHandle waitHandle = _waitHandle;

            if (waitHandle == null)
            {
                // Throw ObjectDisposedException for backward compatibility even though it is not be representative of the issue
                throw new ObjectDisposedException(null, SR.ObjectDisposed_Generic);
            }

            bool success = false;

            try
            {
                int waitResult;

                waitHandle.DangerousAddRef(ref success);

                SynchronizationContext context = SynchronizationContext.Current;
                if (context != null && context.IsWaitNotificationRequired())
                {
                    waitResult = context.Wait(new[] { waitHandle.DangerousGetHandle() }, false, millisecondsTimeout);
                }
                else
                {
                    waitResult = WaitOneCore(waitHandle.DangerousGetHandle(), millisecondsTimeout);
                }

                if (waitResult == WaitAbandoned)
                {
                    throw new AbandonedMutexException();
                }

                return(waitResult != WaitTimeout);
            }
            finally
            {
                if (success)
                {
                    waitHandle.DangerousRelease();
                }
            }
        }
예제 #13
0
        private static bool SignalAndWait(WaitHandle toSignal, WaitHandle toWaitOn, int millisecondsTimeout)
        {
            if (toSignal == null)
            {
                throw new ArgumentNullException(nameof(toSignal));
            }
            if (toWaitOn == null)
            {
                throw new ArgumentNullException(nameof(toWaitOn));
            }
            if (millisecondsTimeout < -1)
            {
                throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
            }

            // The field value is modifiable via the public <see cref="WaitHandle.SafeWaitHandle"/> property, save it locally
            // to ensure that one instance is used in all places in this method
            SafeWaitHandle safeWaitHandleToSignal = toSignal._waitHandle;
            SafeWaitHandle safeWaitHandleToWaitOn = toWaitOn._waitHandle;

            if (safeWaitHandleToSignal == null || safeWaitHandleToWaitOn == null)
            {
                // Throw ObjectDisposedException for backward compatibility even though it is not be representative of the issue
                throw new ObjectDisposedException(null, SR.ObjectDisposed_Generic);
            }

            bool successSignal = false, successWait = false;

            try
            {
                safeWaitHandleToSignal.DangerousAddRef(ref successSignal);
                safeWaitHandleToWaitOn.DangerousAddRef(ref successWait);

                int ret = SignalAndWaitCore(
                    safeWaitHandleToSignal.DangerousGetHandle(),
                    safeWaitHandleToWaitOn.DangerousGetHandle(),
                    millisecondsTimeout);

                if (ret == WaitAbandoned)
                {
                    throw new AbandonedMutexException();
                }

                return(ret != WaitTimeout);
            }
            finally
            {
                if (successWait)
                {
                    safeWaitHandleToWaitOn.DangerousRelease();
                }
                if (successSignal)
                {
                    safeWaitHandleToSignal.DangerousRelease();
                }
            }
        }
예제 #14
0
        private bool JoinInternal(int millisecondsTimeout)
        {
            // This method assumes the thread has been started
            Debug.Assert(!GetThreadStateBit(ThreadState.Unstarted) || (millisecondsTimeout == 0));
            SafeWaitHandle waitHandle = _osHandle;

            // If an OS thread is terminated and its Thread object is resurrected, _osHandle may be finalized and closed
            if (waitHandle.IsClosed)
            {
                return(true);
            }

            // Handle race condition with the finalizer
            try
            {
                waitHandle.DangerousAddRef();
            }
            catch (ObjectDisposedException)
            {
                return(true);
            }

            try
            {
                int result;

                if (millisecondsTimeout == 0)
                {
                    result = (int)Interop.Kernel32.WaitForSingleObject(waitHandle.DangerousGetHandle(), 0);
                }
                else
                {
                    result = WaitHandle.WaitOneCore(waitHandle.DangerousGetHandle(), millisecondsTimeout);
                }

                return(result == (int)Interop.Kernel32.WAIT_OBJECT_0);
            }
            finally
            {
                waitHandle.DangerousRelease();
            }
        }
예제 #15
0
 public Result SetEventOnCompletion(ulong value, WaitHandle?waitHandle)
 {
     if (waitHandle == null)
     {
         return(SetEventOnCompletion(value, IntPtr.Zero));
     }
     else
     {
         return(SetEventOnCompletion(value, waitHandle !.SafeWaitHandle.DangerousGetHandle()));
     }
 }
 /// <summary>
 /// Specifies an event that is to be set when the device state changes. It is also used to turn off event notification.
 /// </summary>
 /// <param name="eventHandle">Handle to the event that is to be set when the device state changes. DirectInput uses the Microsoft Win32 SetEvent function on the handle when the state of the device changes. If the eventHandle parameter is null, notification is disabled.</param>
 /// <returns>A <see cref = "T:SharpDX.Result" /> object describing the result of the operation.</returns>
 public Result SetEventNotification(WaitHandle?eventHandle)
 {
     if (eventHandle == null)
     {
         return(SetEventNotification(IntPtr.Zero));
     }
     else
     {
         return(SetEventNotification(eventHandle !.SafeWaitHandle.DangerousGetHandle()));
     }
 }
예제 #17
0
            public int ReleaseSemaphore(int count)
            {
                IntPtr previousCount = new IntPtr();

                if (!ReleaseSemaphore(SafeWaitHandle.DangerousGetHandle(), count, out previousCount))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                return(previousCount.ToInt32());
            }
예제 #18
0
 public void SetEventOnCompletion(ulong value, WaitHandle?waitHandle)
 {
     if (waitHandle == null)
     {
         SetEventOnCompletion(value, IntPtr.Zero);
     }
     else
     {
         SetEventOnCompletion(value, waitHandle !.SafeWaitHandle.DangerousGetHandle());
     }
 }
예제 #19
0
        /// <summary>
        /// Configure a job object for use by the database connector.  It is
        /// set up so that once the last job handle lapses, all of the
        /// processes joined to the job are terminated.
        /// </summary>
        /// <param name="Job">Supplies a job object handle.</param>
        private static void ConfigureJob(SafeWaitHandle Job)
        {
            JOBOBJECT_EXTENDED_LIMIT_INFORMATION ExtendedLimit;

            ExtendedLimit.BasicLimitInformation.PerProcessUserTimeLimit = 0;
            ExtendedLimit.BasicLimitInformation.PerJobUserTimeLimit     = 0;
            ExtendedLimit.BasicLimitInformation.LimitFlags            = 0;
            ExtendedLimit.BasicLimitInformation.MinimumWorkingSetSize = UIntPtr.Zero;
            ExtendedLimit.BasicLimitInformation.MaximumWorkingSetSize = UIntPtr.Zero;
            ExtendedLimit.BasicLimitInformation.ActiveProcessLimit    = 0;
            ExtendedLimit.BasicLimitInformation.Affinity        = UIntPtr.Zero;
            ExtendedLimit.BasicLimitInformation.PriorityClass   = 0;
            ExtendedLimit.BasicLimitInformation.SchedulingClass = 0;
            ExtendedLimit.IoInfo.ReadOperationCount             = 0;
            ExtendedLimit.IoInfo.WriteOperationCount            = 0;
            ExtendedLimit.IoInfo.OtherOperationCount            = 0;
            ExtendedLimit.IoInfo.ReadTransferCount  = 0;
            ExtendedLimit.IoInfo.WriteTransferCount = 0;
            ExtendedLimit.IoInfo.OtherTransferCount = 0;
            ExtendedLimit.ProcessMemoryLimit        = UIntPtr.Zero;
            ExtendedLimit.JobMemoryLimit            = UIntPtr.Zero;
            ExtendedLimit.PeakProcessMemoryUsed     = UIntPtr.Zero;
            ExtendedLimit.PeakJobMemoryUsed         = UIntPtr.Zero;

            //
            // Set the job to terminate all contained processes on last handle
            // close (for the job itself), and to terminate all processes that
            // are in the job and which have an unhandled exception in lieu of
            // blocking them on the hard error dialog box.
            //

            ExtendedLimit.BasicLimitInformation.LimitFlags = JOBOBJECTLIMIT.KillOnJobClose | JOBOBJECTLIMIT.DieOnUnhandledException;

            int    LimitSize      = Marshal.SizeOf(ExtendedLimit);
            IntPtr JobInformation = Marshal.AllocHGlobal(LimitSize);

            try
            {
                Marshal.StructureToPtr(ExtendedLimit, JobInformation, false);

                if (SetInformationJobObject(Job.DangerousGetHandle(),
                                            JOBOBJECTINFOCLASS.ExtendedLimitInformation,
                                            JobInformation,
                                            (uint)LimitSize) == 0)
                {
                    throw new ApplicationException("SetInformationJobObject failed: " + Marshal.GetLastWin32Error());
                }
            }
            finally
            {
                Marshal.FreeHGlobal(JobInformation);
            }
        }
예제 #20
0
        public bool Set()
        {
            SafeWaitHandle handle = ValidateHandle(out bool release);

            try {
                return(SetEventInternal(handle.DangerousGetHandle()));
            } finally {
                if (release)
                {
                    handle.DangerousRelease();
                }
            }
        }
예제 #21
0
 internal static bool Set(SafeWaitHandle waitHandle)
 {
     waitHandle.DangerousAddRef();
     try
     {
         WaitSubsystem.SetEvent(waitHandle.DangerousGetHandle());
         return(true);
     }
     finally
     {
         waitHandle.DangerousRelease();
     }
 }
예제 #22
0
        internal unsafe void RestartWait()
        {
            long  timeout;
            long *pTimeout = null;  // Null indicates infinite timeout

            if (_millisecondsTimeout != Timeout.UnsignedInfinite)
            {
                timeout  = -10000L * _millisecondsTimeout;
                pTimeout = &timeout;
            }

            // We can use DangerousGetHandle because of DangerousAddRef in the constructor
            Interop.Kernel32.SetThreadpoolWait(_tpWait, _waitHandle.DangerousGetHandle(), (IntPtr)pTimeout);
        }
예제 #23
0
        internal static bool Set(SafeWaitHandle waitHandle)
        {
            bool release = false;

            try {
                waitHandle.DangerousAddRef(ref release);
                return(SetEventInternal(waitHandle.DangerousGetHandle()));
            } finally {
                if (release)
                {
                    waitHandle.DangerousRelease();
                }
            }
        }
예제 #24
0
        public static bool ResetEvent(SafeWaitHandle handle)
        {
            bool release = false;

            try {
                handle.DangerousAddRef(ref release);
                return(ResetEvent_internal(handle.DangerousGetHandle()));
            } finally {
                if (release)
                {
                    handle.DangerousRelease();
                }
            }
        }
예제 #25
0
파일: WaitHandle.cs 프로젝트: wffy/corert
        internal static int WaitOneNative(SafeWaitHandle waitableSafeHandle, long millisecondsTimeout)
        {
            Debug.Assert(millisecondsTimeout >= -1 && millisecondsTimeout <= int.MaxValue);

            waitableSafeHandle.DangerousAddRef();
            try
            {
                return(LowLevelThread.WaitForSingleObject(waitableSafeHandle.DangerousGetHandle(), (int)millisecondsTimeout));
            }
            finally
            {
                waitableSafeHandle.DangerousRelease();
            }
        }
예제 #26
0
        public bool Set()
        {
            SafeWaitHandle waitHandle = ValidateHandle();

            try
            {
                WaitSubsystem.SetEvent(waitHandle.DangerousGetHandle());
                return(true);
            }
            finally
            {
                waitHandle.DangerousRelease();
            }
        }
예제 #27
0
        private void SignalNoCallbacksRunning()
        {
            SafeWaitHandle waitHandle = _notifyWhenNoCallbacksRunning.SafeWaitHandle;

            waitHandle.DangerousAddRef();
            try
            {
                WaitSubsystem.SetEvent(waitHandle.DangerousGetHandle());
            }
            finally
            {
                waitHandle.DangerousRelease();
            }
        }
예제 #28
0
        static int SignalAndWaitOne(SafeWaitHandle waitHandleToSignal,SafeWaitHandle waitHandleToWaitOn, int millisecondsTimeout, bool hasThreadAffinity,  bool exitContext)
        {
            bool releaseHandleToSignal = false, releaseHandleToWaitOn = false;
            try {
                waitHandleToSignal.DangerousAddRef (ref releaseHandleToSignal);
                waitHandleToWaitOn.DangerousAddRef (ref releaseHandleToWaitOn);

                return SignalAndWait_Internal (waitHandleToSignal.DangerousGetHandle (), waitHandleToWaitOn.DangerousGetHandle (), millisecondsTimeout);
            } finally {
                if (releaseHandleToSignal)
                    waitHandleToSignal.DangerousRelease ();
                if (releaseHandleToWaitOn)
                    waitHandleToWaitOn.DangerousRelease ();
            }
        }
예제 #29
0
        private bool JoinCore(int millisecondsTimeout)
        {
            SafeWaitHandle waitHandle = _osHandle;
            int            result;

            waitHandle.DangerousAddRef();
            try
            {
                result = WaitHandle.WaitForSingleObject(waitHandle.DangerousGetHandle(), millisecondsTimeout);
            }
            finally
            {
                waitHandle.DangerousRelease();
            }

            return(result == (int)Interop.Constants.WaitObject0);
        }
예제 #30
0
        public void Wait(WaitHandle launchCompleteHandle, CancellationTokenSource cancellationSource)
        {
            int hr;

            SafeWaitHandle safeWaitHandle  = launchCompleteHandle.SafeWaitHandle;
            bool           addRefSucceeded = false;

            try
            {
                safeWaitHandle.DangerousAddRef(ref addRefSucceeded);
                if (!addRefSucceeded)
                {
                    throw new ObjectDisposedException("launchCompleteHandle");
                }

                IntPtr   nativeHandle = safeWaitHandle.DangerousGetHandle();
                IntPtr[] handles      = { nativeHandle };
                uint     waitResult;

                hr = _messagePump.ModalWaitForObjects(handles, (uint)handles.Length, out waitResult);
                if (hr == 0)
                {
                    return;
                }
                else if (hr == VSConstants.E_PENDING || hr == VSConstants.E_ABORT)
                {
                    // E_PENDING: user canceled
                    // E_ABORT: application exit
                    cancellationSource.Cancel();

                    throw new OperationCanceledException();
                }
                else
                {
                    Debug.Fail("Unexpected result from ModalWaitForObjects");
                    Marshal.ThrowExceptionForHR(hr);
                }
            }
            finally
            {
                if (addRefSucceeded)
                {
                    safeWaitHandle.DangerousRelease();
                }
            }
        }