public override void PerformTest()
        {
            Log("Creating " + _numberOfThreads + " threads");
            Thread[] threads = new Thread[_numberOfThreads];
            for (int i = 0; i < _numberOfThreads; i++)
            {
                threads[i] = new Thread(Work, ThreadPriority.Normal);
            }

            _startedThreads = 0;
            _startedThreadsLock = new Lock();
            _allThreadsStartedLock = new Lock();
            _allThreadsStartedCondition = new Condition(_allThreadsStartedLock);
            _allThreadsStartedLock.Acquire();

            Log("Starting " + _numberOfThreads + " threads"); // TODO: ParametizedThreadStart doesn't work properly
            for (int i = 0; i < _numberOfThreads; i++)
            {
                threads[i].Start();
            }

            // wait for all threads to be running
            _allThreadsStartedCondition.Await();
            _allThreadsStartedLock.Release();

            Log("Waiting for all threads to finish");

            _semaphore.Acquire(_numberOfThreads); // wait for all threads to finish

            Assert(_failedThreads + " threads failed the calculation", _failedThreads == 0);
            Log("All " + _numberOfThreads + " threads finished");

        }
        public void TestAbortThread()
        {
            Lock sync = new Lock();
            TimedCondition aborted = new TimedCondition(sync);
            Thread testThread = new Thread(delegate()
            {
                try
                {
                    Log("Test thread sleeping for 8 seconds..");
                    Thread.Sleep(8000);
                }
                catch (ThreadAbortException)
                {
                    Log("Test thread aborted..");
                    aborted.Signal();
                }
                Fail("This line should never be executed");
            });
            testThread.Start();
            sync.Acquire();
            Log("Aborting test thread in 2 seconds.  Sleeping...");
            Thread.Sleep(2000);
            Log("...awake!  Going to abort the test thread.");
            testThread.Abort();
            Log("Called testThread.Abort()");

            try
            {
                aborted.Await(12000);
            }
            catch (ConditionTimedOutException)
            {
                Fail("Thread was not aborted as expected!");
            }
        }
Beispiel #3
0
 public static LockHolder Hold(Lock l)
 {
     LockHolder h;
     l.Acquire();
     h._lock = l;
     return h;
 }
Beispiel #4
0
        public static LockHolder Hold(Lock l)
        {
            LockHolder h;

            l.Acquire();
            h._lock = l;
            return(h);
        }
Beispiel #5
0
        public override void PerformTest()
        {
            _mainLock = new Lock();

            Thread controllerThread = new Thread(ControllerThreadStart, ThreadPriority.Normal);
            controllerThread.Name = "Controller Thread";

            controllerThread.Start();
            Thread.Sleep(2000);

            Log("Main thread is trying to acquire the main lock...");
            _mainLock.Acquire();
            Log("Main thread got the main lock...");
        }
Beispiel #6
0
        public object Call(string method, object[] args, int timeout)
        {
            XmlHttpRequest xhr = XmlHttpRequestManager.GetXmlHttpRequest();
            Lock l = new Lock();
            l.Acquire();
            TimedCondition condition = new TimedCondition(l);
            OnReadyStateChangeHandler handler = new OnReadyStateChangeHandler(xhr, condition);
            xhr.OnReadyStateChange = (NativeFunction)new VoidDelegate(handler.OnReadyStateChange);
            xhr.Open("POST", ServerUrl, true, Username, Password);
            xhr.SetRequestHeader(RpcMethodRequestHeader, method);
            xhr.Send(Serialize(args));
            if (timeout > 0)
            {
                try
                {
                    // wait for timeout milliseconds
                    condition.Await(timeout);
                }
                catch (ConditionTimedOutException)
                {
                    Logging.Debug("Request timed out!!!");
                    throw new JsonRpcCallTimedOutException(this, method, args, timeout);
                }
            }
            else
            {
                // wait indefinitely
                condition.Await();
            }

            // we have a response from the server, or we couldn't connect
            Logging.Debug("Status code is: " + xhr.Status);
            if (xhr.Status == 200)
            {
                Logging.Debug("Got 200! Response text is " + xhr.ResponseText);
                return Deserialize(xhr.ResponseText);
            }
            else if (xhr.Status == 0)
            {
                Logging.Debug("Request timed out!!!");
                throw new JsonRpcCallTimedOutException(this, method, args, 1000); // TODO: Extract into constant of 1000 ms.  Also this should be some sort of connection refused exception instead
            }
            else
            {
                throw GenerateException(xhr.Status, method, args, xhr.ResponseText);
            }
        }
        public void TestAbortThreadWithState()
        {
            Lock sync = new Lock();
            TimedCondition aborted = new TimedCondition(sync);
            Thread testThread = new Thread(delegate()
            {
                try
                {
                    Log("Test thread sleeping for 8 seconds..");
                    Thread.Sleep(8000);
                }
                catch (ThreadAbortException e)
                {
                    if (e.ExceptionState != null && e.ExceptionState.ToString() == "Exception state")
                    {
                        Log("Test thread aborted with state: " + e.ExceptionState);
                        aborted.Signal();
                    }
                    else
                    {
                        Log("Test thread aborted with unknown state: " + e.ExceptionState);
                    }
                }
                Fail("This line should never be executed");
            });
            testThread.Start();
            sync.Acquire();
            Log("Aborting test thread in 2 seconds");
            Thread.Sleep(2000);
            testThread.Abort("Exception state");

            try
            {
                aborted.Await(12000);
            }
            catch (ConditionTimedOutException)
            {
                Fail("Thread was not aborted as expected!");
            }
        }
Beispiel #8
0
        /// <summary>
        /// Blocks the current thread until it can enter the <see cref="SemaphoreSlim"/>,
        /// using a 32-bit signed integer to measure the time interval,
        /// while observing a <see cref="T:System.Threading.CancellationToken"/>.
        /// </summary>
        /// <param name="millisecondsTimeout">The number of milliseconds to wait, or <see cref="Timeout.Infinite"/>(-1) to
        /// wait indefinitely.</param>
        /// <param name="cancellationToken">The <see cref="T:System.Threading.CancellationToken"/> to observe.</param>
        /// <returns>true if the current thread successfully entered the <see cref="SemaphoreSlim"/>; otherwise, false.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="millisecondsTimeout"/> is a negative number other than -1,
        /// which represents an infinite time-out.</exception>
        /// <exception cref="System.OperationCanceledException"><paramref name="cancellationToken"/> was canceled.</exception>
        public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken)
        {
            CheckDispose();

            // Validate input
            if (millisecondsTimeout < -1)
            {
                throw new ArgumentOutOfRangeException(
                          "totalMilliSeconds", millisecondsTimeout, SR.SemaphoreSlim_Wait_TimeoutWrong);
            }

            cancellationToken.ThrowIfCancellationRequested();

            uint startTime = 0;

            if (millisecondsTimeout != Timeout.Infinite && millisecondsTimeout > 0)
            {
                startTime = TimeoutHelper.GetTime();
            }

            bool        waitSuccessful = false;
            Task <bool> asyncWaitTask  = null;
            bool        lockTaken      = false;

            //Register for cancellation outside of the main lock.
            //NOTE: Register/deregister inside the lock can deadlock as different lock acquisition orders could
            //      occur for (1)this.m_lockObj and (2)cts.internalLock
            CancellationTokenRegistration cancellationTokenRegistration = cancellationToken.InternalRegisterWithoutEC(s_cancellationTokenCanceledEventHandler, this);

            try
            {
                // Perf: first spin wait for the count to be positive, but only up to the first planned yield.
                //       This additional amount of spinwaiting in addition
                //       to Monitor.Enter()’s spinwaiting has shown measurable perf gains in test scenarios.
                //
                SpinWait spin = new SpinWait();
                while (m_currentCount == 0 && !spin.NextSpinWillYield)
                {
                    spin.SpinOnce();
                }
                // entering the lock and incrementing waiters must not suffer a thread-abort, else we cannot
                // clean up m_waitCount correctly, which may lead to deadlock due to non-woken waiters.
                try { }
                finally
                {
                    m_lock.Acquire();
                    lockTaken = true;
                    if (lockTaken)
                    {
                        m_waitCount++;
                    }
                }

                // If there are any async waiters, for fairness we'll get in line behind
                // then by translating our synchronous wait into an asynchronous one that we
                // then block on (once we've released the lock).
                if (m_asyncHead != null)
                {
                    Debug.Assert(m_asyncTail != null, "tail should not be null if head isn't");
                    asyncWaitTask = WaitAsync(millisecondsTimeout, cancellationToken);
                }
                // There are no async waiters, so we can proceed with normal synchronous waiting.
                else
                {
                    // If the count > 0 we are good to move on.
                    // If not, then wait if we were given allowed some wait duration

                    OperationCanceledException oce = null;

                    if (m_currentCount == 0)
                    {
                        if (millisecondsTimeout == 0)
                        {
                            return(false);
                        }

                        // Prepare for the main wait...
                        // wait until the count become greater than zero or the timeout is expired
                        try
                        {
                            waitSuccessful = WaitUntilCountOrTimeout(millisecondsTimeout, startTime, cancellationToken);
                        }
                        catch (OperationCanceledException e) { oce = e; }
                    }

                    // Now try to acquire.  We prioritize acquisition over cancellation/timeout so that we don't
                    // lose any counts when there are asynchronous waiters in the mix.  Asynchronous waiters
                    // defer to synchronous waiters in priority, which means that if it's possible an asynchronous
                    // waiter didn't get released because a synchronous waiter was present, we need to ensure
                    // that synchronous waiter succeeds so that they have a chance to release.
                    Debug.Assert(!waitSuccessful || m_currentCount > 0,
                                 "If the wait was successful, there should be count available.");
                    if (m_currentCount > 0)
                    {
                        waitSuccessful = true;
                        m_currentCount--;
                    }
                    else if (oce != null)
                    {
                        throw oce;
                    }

                    // Exposing wait handle which is lazily initialized if needed
                    if (m_waitHandle != null && m_currentCount == 0)
                    {
                        m_waitHandle.Reset();
                    }
                }
            }
            finally
            {
                // Release the lock
                if (lockTaken)
                {
                    m_waitCount--;
                    m_lock.Release();
                }

                // Unregister the cancellation callback.
                cancellationTokenRegistration.Dispose();
            }

            // If we had to fall back to asynchronous waiting, block on it
            // here now that we've released the lock, and return its
            // result when available.  Otherwise, this was a synchronous
            // wait, and whether we successfully acquired the semaphore is
            // stored in waitSuccessful.

            return((asyncWaitTask != null) ? asyncWaitTask.GetAwaiter().GetResult() : waitSuccessful);
        }
        private static XmlHttpRequest _doSimpleXmlHttpRequest(string url, RequestMethod method, string postData, string username, string password, int timeoutMs)
        {
            XmlHttpRequest xhr = GetXmlHttpRequest();
            Lock l = new Lock();
            l.Acquire();
            Condition condition = new Condition(l);
            if (_driverProcess == null)
            {
                throw new SystemException("XmlHttpRequestManager.Driver was not started.");
            }
            OnReadyStateChangeSignalHandler handler = new OnReadyStateChangeSignalHandler
            {
                XmlHttpRequest = xhr,
                Condition = condition
            };

            // TODO: Use resource manager to ensure these signal senders and handlers get cleaned up
            OnReadyStateChangeSignalSender signalSender = CreateOnReadyStateChangeSignalSender(handler);
            try
            {
                xhr.OnReadyStateChange = (NativeFunction)new NativeVoidDelegate(signalSender.SendSignal);
                string methodString;
                if (method == RequestMethod.Get)
                {
                    methodString = "GET";
                }
                else
                {
                    methodString = "POST";
                }
                xhr.Open(methodString, url, true, username, password);
                xhr.Send(postData);
                if (timeoutMs > 0)
                {
                    if (!condition.Await(timeoutMs))
                    {
                        xhr.OnReadyStateChange = null;
                        throw new XmlHttpRequestTimeoutException("Timed out waiting for " + url, xhr);
                    }
                }
                else
                {
                    condition.Await();
                }
                // TODO: finally blocks are not executed if there is a return statement in the try block.  fix that
            }
            finally
            {
                DestroyOnReadyStateChangeSignalSender(signalSender);
            }
            return xhr;
        }