示例#1
0
        public E Take(int timeout)
        {
            lock (_monitor) {
                if (_sendRequestQueue.Count != 0)
                {
                    SendRequest <E> sendRequest = _sendRequestQueue.First.Value;
                    _sendRequestQueue.RemoveFirst();
                    if (sendRequest.IsBlocking)
                    {
                        sendRequest.Done = true;
                        Monitor.Pulse(_monitor);
                    }

                    return(sendRequest.Message);
                }

                Request <E> request = new Request <E>();
                _requestQueue.AddLast(request);

                TimeoutHolder timeoutHolder = new TimeoutHolder(timeout);
                do
                {
                    try {
                        if (timeoutHolder.Value <= 0L)
                        {
                            _requestQueue.Remove(request);
                            return(default);
示例#2
0
        public Optional <E> receive(int timeout)
        {
            lock (_monitor) {
                var request = new RequestMessage <E>(true);
                waitingQueue.AddFirst(request);
                var timeoutHolder = new TimeoutHolder(timeout);
                do
                {
                    try {
                        if ((timeout = timeoutHolder.Value) <= 0)
                        {
                            waitingQueue.Remove(request);
                            return(Optional <E> .Empty());
                        }

                        Monitor.Wait(_monitor, timeout);
                    }
                    catch (ThreadInterruptedException tie) {
                        if (!request.Busy)
                        {
                            waitingQueue.Remove(request);
                            break;
                        }

                        throw;
                    }
                } while (request.Busy);

                return(Optional <E> .Of(request.Message));
            }
        }
 // receive the nest message
 public bool Receive(out T receivedMessage, int timeout = Timeout.Infinite)
 {
     lock (monitor) {
         if (CanReceive())
         {
             receivedMessage = ReceiveSideEffect();
             return(true);
         }
         TimeoutHolder th = new TimeoutHolder(timeout);
         do
         {
             if ((timeout = th.Value) == 0)
             {
                 receivedMessage = default(T);
                 return(false);
             }
             try {
                 Monitor.Wait(monitor, timeout);
             } catch (ThreadInterruptedException) {
                 // .NET monitors can ignore notifications when there is a race between
                 // the notification and the interrupt. So, we must regenerate the notification
                 // if there are pending messages, in order to propagate the notification to
                 // another blocked thread
                 if (CanAcquire())
                 {
                     Monitor.Pulse(monitor);
                 }
                 throw;
             }
         } while (!CanReceive());
         receivedMessage = ReceiveSideEffect();
         return(true);
     }
 }
示例#4
0
    // Wait until the event is signalled
    public bool Wait(int timeout = Timeout.Infinite)
    {
        lock (monitor) {
            // If the event is already signalled, return true
            if (signalState)
            {
                return(true);
            }

            // create an instance of TimeoutHolder to support timeout adjustments
            TimeoutHolder th = new TimeoutHolder(timeout);

            // loop until the event is signalled, the specified timeout expires or
            // the thread is interrupted.

            int arrivalGeneration = signalStateGeneration;
            do
            {
                if ((timeout = th.Value) == 0)
                {
                    return(false);                              // timeout expired
                }
                Monitor.Wait(monitor, timeout);
            } while (arrivalGeneration == signalStateGeneration);
            return(true);
        }
    }
    // Acquire one permit from the semaphore
    public bool Acquire(int timeout = Timeout.Infinite)
    {
        // try to acquire one permit, if available
        if (TryAcquire())
        {
            return(true);
        }

        // no permits available; if a null time out was specified, return failure.
        if (timeout == 0)
        {
            return(false);
        }

        // if a time out was specified, get a time reference
        TimeoutHolder th = new TimeoutHolder(timeout);

        lock (monitor) {
            // the current thread declares itself as a waiter..
            waiters++;

            /**
             * The .NET Memory Model does not guarantees non-reordering of previous volatile write
             *  of "waiters" with the next volatile read of "permits", so we must EXPLICITLY
             *  insert a Full Fence to ensure that this algorithm works!
             */
            Interlocked.MemoryBarrier();
            try {
                do
                {
                    // after increment waiters, we must recheck if acquire is possible!
                    if (TryAcquire())
                    {
                        return(true);
                    }
                    // check if the specified timeout expired
                    if ((timeout = th.Value) == 0)
                    {
                        return(false);
                    }
                    Monitor.Wait(monitor, timeout);
                } while (true);
            } catch (ThreadInterruptedException) {
                // if we were interrupted and there are permits available, we can have
                // been notified and interrupted.
                // so, we leave this method throwing ThreadInterruptException, but before
                // we regenerate the notification, if there are available permits
                //
                if (permits > 0)
                {
                    Monitor.Pulse(monitor);
                }
                throw;                 // re-throw thread interrupted exception
            } finally {
                // the current thread is no longer a waiter
                waiters--;
            }
        }
    }
示例#6
0
    // Wait until the event is signalled
    public bool Wait(int timeout = Timeout.Infinite)
    {
        // If the event is signalled, return true
        if (tryAcquire())
        {
            return(true);
        }

        // the event is not signalled; if a null time out was specified, return failure.
        if (timeout == 0)
        {
            return(false);
        }

        // if a time out was specified, get a time reference
        TimeoutHolder th = new TimeoutHolder(timeout);

        lock (monitor) {
            // get the current setVersion and declare the current thread as a waiter.
            int sv = setVersion;
            waiters++;

            /**
             * before we read the "signaled" volatile variable, we need to make sure that the increment
             * of *waiters* is visible to all processors.
             * In .NET this means interpose a full-fence memory barrier.
             */
            Interlocked.MemoryBarrier();

            try {
                /**
                 * after declare this thread as waiter, we must recheck the "signaled" in order
                 * to capture a check that ocorred befor we increment the waiters.
                 */
                if (tryAcquire())
                {
                    return(true);
                }

                // loop until the event is signalled, the specified timeout expires or
                // the thread is interrupted.
                do
                {
                    // check if the wait timed out
                    if ((timeout = th.Value) == 0)
                    {
                        // the specified time out elapsed, so return failure
                        return(false);
                    }

                    Monitor.Wait(monitor, timeout);
                } while (sv == setVersion);
                return(true);
            } finally {
                // at the end, decrement the number of waiters
                waiters--;
            }
        }
    }
示例#7
0
        public bool Wait(int timeout)   // throws InterruptedException
        {
            if (signaled)
            {
                return(true);
            }
            if (timeout == 0)
            {
                return(false);
            }
            lock (monitor) {
                int currentVersion = signalVersion;

                try {
                    waiters++;

                    // necessary to avoid reordering observation between the write
                    // above and the read below (.Net permits this write-read reordering)
                    Thread.MemoryBarrier();

                    if (signaled)
                    {
                        return(true);
                    }



                    // prepare wait

                    TimeoutHolder th = new TimeoutHolder(timeout);
                    do
                    {
                        Monitor.Wait(monitor, th.Value);
                        if (currentVersion != signalVersion)
                        {
                            return(true);
                        }

                        if (th.Timeout)
                        {
                            return(false);   // abort operation on timeout
                        }
                    }while (true);
                }
                catch (ThreadInterruptedException) {
                    if (currentVersion != signalVersion)
                    {
                        Thread.CurrentThread.Interrupt();
                        return(true);
                    }
                    throw;
                }
                finally {
                    waiters--;
                }
            }
        }
示例#8
0
    // acquires the specified number of permits; returns false if times out
    public bool Acquire(int acquires, int timeout = Timeout.Infinite)
    {
        lock (monitor) {
            if (reqQueue.Count == 0 && CanAcquire(acquires))
            {
                AcquireSideEffect(acquires);
                return(true);
            }
            Request request = new Request(acquires);
            reqQueue.AddLast(request);  // enqueue "request" at the end of  "reqQueue"
            TimeoutHolder th = new TimeoutHolder(timeout);
            do
            {
                if ((timeout = th.Value) <= 0)
                {
                    reqQueue.Remove(request);

                    // after remove the request of the current thread from queue, *it is possible*
                    // that the current synhcronization state allows now to satisfy other queued
                    // acquire(s).
                    if (CurrentSynchStateAllowsAcquire())
                    {
                        PerformPossibleAcquires();
                    }

                    return(false);
                }
                try {
                    MonitorEx.Wait(monitor, request, timeout);  // *wait on a private condition variable*
                } catch (ThreadInterruptedException) {
                    // if the acquire operation was already done, re-assert interrupt
                    // and return normally; else remove request from queue and throw
                    // ThreadInterruptedException.
                    if (request.done)
                    {
                        Thread.CurrentThread.Interrupt();
                        return(true);
                    }
                    reqQueue.Remove(request);

                    // after remove the request of the current thread from queue, *it is possible*
                    // that the current synhcronization state allows now to satisfy other queued
                    // acquire(s).
                    if (CurrentSynchStateAllowsAcquire())
                    {
                        PerformPossibleAcquires();
                    }

                    throw;      // ThreadInterruptedException
                }
            } while (!request.done);
            // the request was completed
            return(true);
        }
    }
示例#9
0
        /**
         *  Acquire operation.
         * @param timeout max waiting time
         * @return  true if operation succeeded, false if timeout
         * @throws ThreadInterruptedException
         */
        public bool Acquire(int timeout)   //  throws InterruptedException
        // fast path
        {
            if (tryAcquire())
            {
                return(true);
            }

            if (timeout == 0) // fail!
            {
                return(false);
            }

            lock (monitor) {
                waiters++;

                // The following (complete) barrier is necessary on CLI to avoid reordering of the waiters write in line 43
                // and the permits read on the execution of tryAcquire!
                Thread.MemoryBarrier();

                if (tryAcquire())   // last try
                {
                    waiters--;
                    return(true);
                }
                try {
                    // prepare wait
                    TimeoutHolder th = new TimeoutHolder(timeout);
                    do
                    {
                        int refTime = Environment.TickCount;
                        Monitor.Wait(monitor, th.Remaining);
                        if (tryAcquire())
                        {
                            return(true);
                        }
                        if (th.Timeout)
                        {
                            return(false);
                        }
                    }while (true);
                }
                catch (ThreadInterruptedException e) {
                    if (permits > 0)
                    {
                        Monitor.Pulse(monitor);
                    }
                    throw e;
                }
                finally {
                    waiters--;
                }
            }
        }
        public bool Acquire(int units, int timeout)
        {
            lock (monitor) {
                // non blocking path
                if (requests.Count == 0 && permits >= units)
                {
                    permits -= units;
                    return(true);
                }

                // try path
                if (timeout == 0)
                {
                    return(false);
                }

                // prepare wait
                TimeoutHolder            th   = new TimeoutHolder(timeout);
                Request                  req  = new Request(units);
                LinkedListNode <Request> node = requests.AddLast(req);

                do
                {
                    try {
                        req.Wait(monitor, th.Remaining);
                        //Monitor.Wait(monitor, th.Remaining);
                        if (node.Value.Processed)
                        {
                            return(true);
                        }
                        if (th.Timeout)
                        {
                            requests.Remove(node);
                            notifyWaiters();
                            return(false);
                        }
                    }
                    catch (ThreadInterruptedException) {
                        if (node.Value.Processed)
                        {
                            Thread.CurrentThread.Interrupt();
                            return(true);
                        }
                        requests.Remove(node);
                        notifyWaiters();
                        throw;
                    }
                }while (true);
            }
        }
示例#11
0
 public bool Exchange(T mine, int timeout, out T yours)
 {
     yours = default(T);      // just to satisfy the compiler
     lock (monitor) {
         if (current != null) // a partner is waiting...
         // process the pairing using execution delegation technique
         {
             yours       = current.msg;
             current.msg = mine;
             Monitor.Pulse(monitor);
             current = null; // the pairing is done, so we must "hide" it
             return(true);
         }
         // prepare waiting
         PairRequest   myPair = current = new PairRequest(mine);
         TimeoutHolder th     = new TimeoutHolder(timeout);
         try {
             do
             {
                 Monitor.Wait(monitor, th.Value);
                 // check success
                 if (!object.ReferenceEquals(myPair.msg, mine))    // the pairing is done
                 {
                     yours = myPair.msg;
                     return(true);
                 }
                 // check timeout
                 if (th.Timeout)
                 {
                     // abort current pairing
                     current = null;
                     return(false);
                 }
             } while (true);
         }
         catch (ThreadInterruptedException) {
             if (!object.ReferenceEquals(myPair.msg, mine))   // the pairing is done
             {
                 yours = myPair.msg;
                 Thread.CurrentThread.Interrupt();
                 return(true);
             }
             // abort current pairing
             current = null;
             throw;
         }
     }
 }
        public bool Acquire(int units, int timeout)   // throws InterruptedException
        {
            lock (monitor) {
                // non blocking path
                if (permits >= units && waiters.Count == 0)
                {
                    permits -= units;
                    return(true);
                }
                if (timeout == 0)
                {
                    return(false);
                }
                // blocking path
                // prepare wait
                TimeoutHolder th   = new TimeoutHolder(timeout);
                var           node = waiters.AddLast(new Request(units));

                try {
                    do
                    {
                        // use waiters node as a new condition!
                        monitor.Wait(node, th.Value);
                        if (node.Value.granted)
                        {
                            return(true);
                        }
                        if (th.Timeout)
                        {
                            waiters.Remove(node);
                            notifyWaiters();
                            return(false);
                        }
                    }while (true);
                }
                catch (ThreadInterruptedException e) {
                    if (node.Value.granted)
                    {
                        Thread.CurrentThread.Interrupt();
                        return(true);
                    }
                    waiters.Remove(node);
                    notifyWaiters();
                    throw e;
                }
            }
        }
示例#13
0
        public bool Acquire(int timeout)
        {
            if (TryAcquire())
            {
                return(true);
            }
            if (timeout == 0)
            {
                return(false);
            }
            TimeoutHolder th = new TimeoutHolder(timeout);

            lock (monitor) {
                waiters++;

                try {
                    if (TryAcquire())
                    {
                        return(true);
                    }

                    while (true)
                    {
                        Monitor.Wait(th.Value);
                        if (TryAcquire())
                        {
                            return(true);
                        }
                        if (th.Timeout)
                        {
                            return(false);
                        }
                    }
                }
                catch (ThreadInterruptedException) {
                    if (permits > 0)
                    {
                        Monitor.Pulse(monitor);
                    }
                    throw;
                }
                finally {
                    waiters--;
                }
            }
        }
示例#14
0
        public bool Transfer(E message, int timeout)
        {
            lock (_monitor) {
                if (_requestQueue.Count != 0)
                {
                    Request <E> request = _requestQueue.First.Value;
                    _requestQueue.RemoveFirst();
                    request.Message = message;
                    request.Done    = true;
                    Monitor.Pulse(_monitor);
                }
                else
                {
                    SendRequest <E> request = new SendRequest <E>(message, BLOCKING);
                    _sendRequestQueue.AddLast(request);
                    TimeoutHolder timeoutHolder = new TimeoutHolder(timeout);
                    do
                    {
                        try {
                            if (timeoutHolder.Value <= 0L)
                            {
                                _sendRequestQueue.Remove(request);
                                return(false);
                            }

                            Monitor.Wait(_monitor, timeout);
                        }
                        catch (ThreadInterruptedException ie) {
                            if (request.Done)
                            {
                                Thread.CurrentThread.Interrupt();
                                break;
                                //will return true after the interruption, because the operation succeeded
                            }

                            _sendRequestQueue.Remove(request);
                            throw ie;
                        }
                    } while (_requestQueue.Count == 0);
                }

                return(true);
            }
        }
示例#15
0
    public bool Wait(int timeout = Timeout.Infinite)
    {
        lock (monitor) {
            // If the event is already signalled, return true
            if (signalState)
            {
                return(true);
            }

            // enqueue a request on the request queue
            LinkedListNode <bool> requestNode = reqQueue.AddLast(false);

            // create an instance of TimeoutHolder to support timeout adjustments
            TimeoutHolder th = new TimeoutHolder(timeout);

            // loop until our request is satisfied, the specified timeout expires
            // or the thread is interrupted.

            do
            {
                if ((timeout = th.Value) == 0)
                {
                    // remove our request from "reqQueue"
                    reqQueue.Remove(requestNode);
                    return(false);                              // return failure: timeout expired
                }
                try {
                    Monitor.Wait(monitor, timeout);
                } catch (ThreadInterruptedException) {
                    // as this acquire operation has no side effects we can choose to
                    // throw ThreadInterruptedException instead of giving the operation
                    // completed successfully.
                    // anyway, we must remove the request from the queue if it is stiil
                    // inserted.
                    if (!requestNode.Value)
                    {
                        reqQueue.Remove(requestNode);
                    }
                    throw;
                }
            } while (!requestNode.Value);
            return(true);
        }
    }
示例#16
0
 public bool Acquire(int requests, int timeout)   // throws InterruptedException
 {
     lock (monitor) {
         // non blocking path
         if (permits >= requests && waiters.Count > 0)
         {
             permits -= requests;
             return(true);
         }
         if (timeout == 0)
         {
             return(false);
         }
         // blocking path
         // prepare wait
         TimeoutHolder th   = new TimeoutHolder(timeout);
         var           node = waiters.AddLast(requests);
         try {
             do
             {
                 Monitor.Wait(monitor, th.Value);
                 if (waiters.First == node && permits >= requests)
                 {
                     waiters.RemoveFirst();
                     permits -= requests;
                     notifyWaiters();
                     return(true);
                 }
                 if (th.Timeout)
                 {
                     waiters.Remove(node);
                     notifyWaiters();
                     return(false);
                 }
             }while (true);
         }
         catch (ThreadInterruptedException e) {
             waiters.Remove(node);
             notifyWaiters();
             throw e;
         }
     }
 }
示例#17
0
        public Optional <T> Exchange(T mydata, int timeout)
        {
            lock (_lock) {
                if (_waiter != null)
                {
                    Console.WriteLine("Swapee value = " + _waiter.MyData + ", swaper value = " + mydata);
                    mydata         = _waiter.Swap(mydata);
                    _waiter.IsDone = true;
                    Monitor.Pulse(_waiter.Lock);
                    return(Optional <T> .Of(mydata));
                }

                TimeoutHolder timeoutHolder = new TimeoutHolder(timeout);
                _waiter = new Waiter <T>(mydata, _lock);

                do
                {
                    try {
                        Console.WriteLine(_waiter.MyData);
                        if ((timeout = timeoutHolder.Value) <= 0)
                        {
                            return(Optional <T> .Empty());
                        }

                        Monitor.Wait(_waiter.Lock, timeout);
                    }
                    catch (ThreadInterruptedException e) {
                        if (_waiter.IsDone)
                        {
                            Console.WriteLine("Done = true, value = " + _waiter.MyData);
                            Thread.CurrentThread.Interrupt();
                            break;
                        }

                        throw;
                    }
                } while (!_waiter.IsDone);

                Console.WriteLine("Will return value = " + _waiter.MyData);
                return(Optional <T> .Of(_waiter.MyData));
            }
        }
示例#18
0
 // receive the next message from the queue
 public bool Receive(out T receivedMsg, int timeout = Timeout.Infinite)
 {
     lock (monitor) {
         if (reqQueue.Count == 0 && CanReceive())
         {
             receivedMsg = ReceiveSideEffect();
             return(true);
         }
         TimeoutHolder th      = new TimeoutHolder(timeout);
         Request       request = new Request();
         reqQueue.AddLast(request);  // enqueue "request" at the end of  "reqQueue"
         do
         {
             if ((timeout = th.Value) == 0)
             {
                 // the specified time limit has expired.
                 // Here we know that our request was not satisfied.
                 reqQueue.Remove(request);
                 receivedMsg = default(T);
                 return(false);
             }
             try {
                 Monitor.Wait(monitor, timeout);
             } catch (ThreadInterruptedException) {
                 // if the acquire operation was already done, re-assert interrupt
                 // and return normally; else remove request from queue and throw
                 // ThreadInterruptedException.
                 if (request.done)
                 {
                     Thread.CurrentThread.Interrupt();
                     break;
                 }
                 // remove the request from queue and throw ThreadInterruptedException
                 reqQueue.Remove(request);
                 throw;
             }
         } while (!request.done);
         // the request was satisfied, retrieve the received message
         receivedMsg = request.receivedMsg;
         return(true);
     }
 }
 // acquire "acquires" permits
 public bool Acquire(int acquires, int timeout = Timeout.Infinite)
 {
     lock (monitor) {
         if (CanAcquire(acquires))
         {
             // there are sufficient permits available, take them
             AcquireSideEffect(acquires);
             return(true);
         }
         TimeoutHolder th = new TimeoutHolder(timeout);
         do
         {
             if ((timeout = th.Value) == 0)
             {
                 return(false);
             }
             Monitor.Wait(monitor, timeout);
         } while (!CanAcquire(acquires));
         AcquireSideEffect(acquires);
         return(true);
     }
 }
示例#20
0
 public bool Acquire(int timeout)   // throws InterruptedException
 {
     lock (monitor) {
         // non blocking path
         if (permits > 0)
         {
             --permits;
             return(true);
         }
         if (timeout == 0)
         {
             return(false);
         }
         // blocking path
         TimeoutHolder th = new TimeoutHolder(timeout);
         try {
             do
             {
                 Monitor.Wait(th.Value);
                 if (permits > 0)
                 {
                     --permits;
                     return(true);
                 }
                 if (th.Timeout)
                 {
                     return(false);
                 }
             }while (true);
         }
         catch (ThreadInterruptedException e) {
             if (permits > 0)
             {
                 Monitor.Pulse(monitor);
             }
             throw e;
         }
     }
 }
        public bool Await(int timeout)
        {
            lock (monitor) {
                if (signaled)
                {
                    return(true);
                }
                if (timeout == 0)
                {
                    return(false);
                }

                TimeoutHolder th          = new TimeoutHolder(timeout);
                int           currVersion = notifyVersion;
                try {
                    do
                    {
                        Monitor.Wait(monitor, th.Value);
                        if (currVersion != notifyVersion)
                        {
                            return(true);
                        }
                        if (th.Timeout)
                        {
                            return(false);
                        }
                    }while (true);
                }
                catch (ThreadInterruptedException) {
                    if (signaled)
                    {
                        Thread.CurrentThread.Interrupt();
                        return(true);
                    }
                    throw;
                }
            }
        }
 public bool Acquire(int requests, int timeout)   // throws InterruptedException
 {
     lock (monitor) {
         // non blocking path
         if (permits >= requests)
         {
             permits -= requests;
             return(true);
         }
         if (timeout == 0)
         {
             return(false);
         }
         // blocking path
         TimeoutHolder th = new TimeoutHolder(timeout);
         try {
             do
             {
                 Monitor.Wait(monitor, th.Value);
                 if (permits >= requests)
                 {
                     permits -= requests;
                     return(true);
                 }
                 if (th.Timeout)
                 {
                     return(false);
                 }
             }while (true);
         }
         catch (ThreadInterruptedException e) {
             // In this case no exception treatment is necessary
             // the catch clausule is redundant
             throw e;
         }
     }
 }
 // The acquire operation
 public bool Acquire(AcquireArgs acquireArgs, out AcquireResult result, int timeout = Timeout.Infinite)
 {
     lock (monitor) {
         if (CanAcquire(acquireArgs))
         {
             // do an immediate acquire
             result = AcquireSideEffect(acquireArgs);
             return(true);
         }
         TimeoutHolder th = new TimeoutHolder(timeout);
         do
         {
             if ((timeout = th.Value) == 0)
             {
                 result = default(AcquireResult);
                 return(false);
             }
             try {
                 Monitor.Wait(monitor, timeout);
             } catch (ThreadInterruptedException) {
                 // if notification was made with Monitor.Pulse, the single notification
                 // may be lost if the blocking of the notified thread was interrupted,
                 // so, if an acquire is possible, we notify another blocked thread, if any.
                 // anyway we propagate the interrupted exception
                 if (CanAcquire(acquireArgs))
                 {
                     Monitor.Pulse(monitor);
                 }
                 throw;
             }
         } while (!CanAcquire(acquireArgs));
         // now we can complete the acquire after blocking in the monitor
         result = AcquireSideEffect(acquireArgs);
         return(true);
     }
 }
示例#24
0
    // generic acquire operation; returns false when it times out
    public bool Acquire(AcquireArgs acquireArgs, out AcquireResult result, int timeout = Timeout.Infinite)
    {
        lock (monitor) {
            if (reqQueue.Count == 0 && CanAcquire(acquireArgs))
            {
                result = AcquireSideEffect(acquireArgs);
                return(true);
            }
            Request request = new Request(acquireArgs);
            reqQueue.AddLast(request);  // enqueue "request" at the end of the request queue
            TimeoutHolder th = new TimeoutHolder(timeout);
            do
            {
                if ((timeout = th.Value) == 0)
                {
                    // the timeout limit has expired - here we are sure that the acquire resquest
                    // is still pending. So, we remove the request from the queue and return failure.
                    reqQueue.Remove(request);

                    // After remove the request of the current thread from queue, *it is possible*
                    // that the current synhcronization state allows now to satisfy other queued
                    // acquire(s).
                    if (CurrentSynchStateAllowsAquire())
                    {
                        PerformPossibleAcquires();
                    }

                    result = default(AcquireResult);
                    return(false);
                }
                try {
                    MonitorEx.Wait(monitor, request, timeout);  // *wait on a private condition var*
                } catch (ThreadInterruptedException) {
                    // the thread may be interrupted when the requested acquire operation
                    // is already performed, in which case you can no longer give up
                    if (request.done)
                    {
                        // re-assert the interrupt and return normally, indicating to the
                        // caller that the operation was successfully completed
                        Thread.CurrentThread.Interrupt();
                        break;
                    }
                    // remove the request from the queue and throw ThreadInterruptedException
                    reqQueue.Remove(request);

                    // After remove the request of the current thread from queue, *it is possible*
                    // that the current synhcronization state allows now to satisfy other queued
                    // acquire(s).
                    if (CurrentSynchStateAllowsAquire())
                    {
                        PerformPossibleAcquires();
                    }

                    throw;      // ThreadInterruptedException
                }
            } while (!request.done);
            // the request acquire operation completed successfully
            result = request.acquireResult;
            return(true);
        }
    }
示例#25
0
        public Optional <E> Get(int timeout)
        {
            lock (_monitor) {
                /*
                 * If exception has occurred, then every calls to get result
                 * in that same exception getting thrown again
                 */
                if (_state == State.Error)
                {
                    throw _exceptionOccurred;
                }

                /*
                 * If the value is already computed and the number of lives is greater than 0,
                 * then the value is returned to caller right away.
                 */
                if (_currentLives > 0 && _state == State.Computed)
                {
                    return(DecrementCheckAndReturn());
                }


                /*
                 * In any other case, either the value needs to be recalculated, or is already being
                 * computed by another thread. The current thread calculate the value, or wait,
                 * if the latter is the case.
                 */
                if (_state == State.Computing)
                {
                    var timeoutHolder = new TimeoutHolder(timeout);
                    do
                    {
                        if ((timeout = timeoutHolder.Value) < 0L)
                        {
                            return(Optional <E> .Empty());
                        }

                        Monitor.Wait(_monitor, timeout);

                        if (_state == State.Computed && _currentLives > 0)
                        {
                            return(DecrementCheckAndReturn());
                        }

                        if (_state == State.Error)
                        {
                            throw _exceptionOccurred;
                        }
                    } while (_state == State.Computing);
                }

                _state = State.Computing;
            }

            /*
             * The current thread is going to calculate the new value, by invoking the supplier.
             */
            E         v  = default;
            Exception ex = default;

            try {
                v             = _supplier();
                _currentLives = _lives;
            }
            catch (Exception e) {
                ex = e;
            }

            /*
             * In the end, if an unchecked exception has occurred, it shall be thrown, and State state
             * shall be put to ERROR. Else, the value field is updated and returned.
             */
            lock (_monitor) {
                Monitor.PulseAll(_monitor);
                if (ex != null)
                {
                    _exceptionOccurred = ex;
                    _state             = State.Error;
                    throw _exceptionOccurred;
                }

                _value = v;
                _state = State.Computed;
                return(DecrementCheckAndReturn());
            }
        }
示例#26
0
 public TimeoutHolder Timeout(float time, Action callback)
 {
     var th = new TimeoutHolder { Time = time, Callback = callback };
     timeouts.Add(th);
     return th;
 }
示例#27
0
        public async static Task <Response> ShutDown(Request request)
        {
            if (toShutDown)
            {
                return new Response {
                           Status = 503, Payload = toShutDownPayload
                }
            }
            ;
            toShutDown = true;

            if (inServiceRequests == 0)
            {
                return new Response {
                           Status = 200, Payload = toShutDownPayload
                }
            }
            ;

            String tHeader;
            int    timeout;

            request.Headers.TryGetValue("timeout", out tHeader);
            if (tHeader == null)
            {
                timeout = Timeout.Infinite;
            }
            else
            {
                int.TryParse(tHeader, out timeout);
            }
            TimeoutHolder th = new TimeoutHolder(timeout);

            lock (_lock)
            {
                do
                {
                    try
                    {
                        if ((timeout = th.Value) == 0)
                        {
                            return(new Response {
                                Status = 204, Payload = timeoutPayload
                            });
                        }
                        else if (inServiceRequests == 0)
                        {
                            return new Response {
                                       Status = 200, Payload = toShutDownPayload
                            }
                        }
                        ;
                        Monitor.Wait(_lock, timeout);
                    }
                    catch (ThreadInterruptedException)
                    {
                        if (inServiceRequests == 0)
                        {
                            return new Response {
                                       Status = 200, Payload = toShutDownPayload
                            }
                        }
                        ;
                        else
                        {
                            return new Response {
                                       Status = 500, Payload = serverError
                            }
                        };
                    }
                } while (true);
            }
        }
    }
}
示例#28
0
        //---------------------------------------------------------------------
        // Synchronous
        //--
        public bool WaitEx(int timeout, CancellationToken ctk)
        {
            bool          interrupted   = false;
            Waiter <Data> waiter        = null;
            bool          ownsTheWaiter = false;

            lock (_lock)
            {
                if (currentPermits > 0)
                {
                    currentPermits -= 1;
                    return(true);
                }
                // if the current thread must block, check immediate cancelers
                if (timeout == 0)
                {
                    return(false);
                }
                ctk.ThrowIfCancellationRequested();

                // create a synchronous waiter node and insert it in the wait queue
                waiter = new SyncWaiter <Data>(new Data(), ctk, SyncUnlink);
                DListNode.AddLast(waiters, waiter);
                waiter.Enable();

                // wrap timeout value with timeout holder, in order to support timeout adjust
                TimeoutHolder th = new TimeoutHolder(timeout);

                // wait until the request is staisfied, timeout expires or cancellation
                do
                {
                    try
                    {
                        if ((timeout = th.Value) == 0)
                        {
                            ownsTheWaiter = TrySetStateAndRemoveWaiter(waiter, WaiterState.TIMED_OUT);
                            break;
                        }
                        // wait on the monitor's condition variable
                        MonitorEx.Wait(_lock, waiter, timeout);
                    }
                    catch (ThreadInterruptedException)
                    {
                        interrupted   = true;
                        ownsTheWaiter = TrySetStateAndRemoveWaiter(waiter, WaiterState.INTERRUPTED);
                        break;
                    }
                } while (waiter.State == WaiterState.WAITING);
            }

            // this processing is private of the current thread, so we can do it without
            // owning the lock.
            if (ownsTheWaiter)
            {
                waiter.CancelCancellation();
            }
            if (waiter.State == WaiterState.INTERRUPTED)
            {
                throw new ThreadInterruptedException();
            }
            if (interrupted)
            {
                Thread.CurrentThread.Interrupt();
            }
            if (waiter.State == WaiterState.CANCELED)
            {
                throw new OperationCanceledException(ctk);
            }
            return(waiter.State == WaiterState.SUCCESS);
        }
示例#29
0
 public void CancelTimeout(TimeoutHolder timeout)
 {
     timeouts.Remove(timeout);
 }