// do the acquire operation
 public AcquireResult Acquire(AcquireArgs acquireArgs)
 {
     _lock.Acquire();
     try {
         while (!CanAcquire(acquireArgs))
         {
             enqueue the current thread on the "waitQueue" sensible to posterior wakeups;
             int depth = _lock.ReleaseAll();
             block current thread until it is waked up by a releaser thread;
             _lock.ReAcquire(depth);
         }
         return(AcquireSideEffect(acquireArgs));
     } finally {
         _lock.Release();
     }
 }
예제 #2
0
 // generic acquire operation
 public AcquireResult Acquire(AcquireArgs acquireArgs)
 {
     _lock.Acquire();
     try {
         if (reqQueue.Count == 0 && CanAcquire(acquireArgs))
         {
             return(AcquireSideEffect(acquireArgs));
         }
         Request request = new Request(acquireArgs);
         reqQueue.AddLast(request);          // enqueue the "request" at the end of the request queue
         do
         {
             enqueue current thread on the "waitQueue" sensible to posterior wakeups done by "_lock" owners;
             int depth = _lock.ReleaseAll();
             block current thread until it is waked up by a releaser thread;
             _lock.ReAcquire(depth);
         } while (!request.done);
         // the requested acquire operation completed successfully
         return(request.acquireResult);
     } finally {
         _lock.Release();
     }
 }
 // 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);
     }
 }
 // executes the side effect processing related to a successful acquire
 private AcquireResult AcquireSideEffect(AcquireArgs acquireArgs)
 {
     update "synchState" according to "acquireArgs" after a successful acquire;
     returns "the-proper-acquire-result"
 }
 // check if synchronization state allows an immediate acquire
 private bool CanAcquire(AcquireArgs acquireArgs)
 {
     returns true if "syncState" satisfies an immediate acquire according to "acquireArgs";
 }
예제 #6
0
        bool done;                              // true when the acquire is done

        Request(AcquireArgs args)
        {
            acquireArgs = args;
        }
예제 #7
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);
        }
    }
예제 #8
0
        internal bool done;                          // true when the acquire is done

        internal Request(AcquireArgs args)
        {
            acquireArgs = args;
        }