Esempio n. 1
0
 /// <summary>V the semaphore (add 1 unit to it).</summary>
 public void V()
 {
     // Lock so we can work in peace. This works because lock is actually
     // built around Monitor.
     using (TimedLock.Lock(this))
     {
         // Release our hold on the unit of control. Then tell everyone
         // waiting on this object that there is a unit available.
         _count++;
         Monitor.Pulse(this);
     }
 }
Esempio n. 2
0
        /// <summary>
        /// Attempts to obtain a lock on the specified object for up to
        /// the specified timeout.
        /// </summary>
        /// <param name="o"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public static TimedLock Lock(object o, TimeSpan timeout)
        {
            Thread.BeginCriticalRegion();
            TimedLock tl = new TimedLock(o);

            if (!Monitor.TryEnter(o, timeout))
            {
                // Failed to acquire lock.
#if DEBUG
                GC.SuppressFinalize(tl.leakDetector);
                throw new LockTimeoutException(o);
#else
                throw new LockTimeoutException();
#endif
            }
            return(tl);
        }
Esempio n. 3
0
 /// <summary>P the semaphore (take out 1 unit from it).</summary>
 public void P()
 {
     // Lock so we can work in peace. This works because lock is actually
     // built around Monitor.
     using (TimedLock.Lock(this))
     {
         // Wait until a unit becomes available. We need to wait
         // in a loop in case someone else wakes up before us. This could
         // happen if the Monitor.Pulse statements were changed to Monitor.PulseAll
         // statements in order to introduce some randomness into the order
         // in which threads are woken.
         while (_count <= 0)
         {
             Monitor.Wait(this, Timeout.Infinite);
         }
         _count--;
     }
 }
Esempio n. 4
0
        /// <summary>A thread worker function that processes items from the work queue.</summary>
        private static void ProcessQueuedItems()
        {
            // Process indefinitely
            while (true)
            {
                // Get the next item in the queue. If there is nothing there, go to sleep
                // for a while until we're woken up when a callback is waiting.
                WaitingCallback callback = null;
                while (callback == null)
                {
                    // Try to get the next callback available. We need to lock on the
                    // queue in order to make our count check and retrieval atomic.
                    using (TimedLock.Lock(_waitingCallbacks.SyncRoot))
                    {
                        if (_waitingCallbacks.Count > 0)
                        {
                            try { callback = (WaitingCallback)_waitingCallbacks.Dequeue(); }
                            catch { }                             // make sure not to fail here
                        }
                    }

                    // If we can't get one, go to sleep.
                    if (callback == null)
                    {
                        _workerThreadNeeded.WaitOne();
                    }
                }

                // We now have a callback. Execute it. Make sure to accurately
                // record how many callbacks are currently executing.
                try
                {
                    Interlocked.Increment(ref _inUseThreads);
                    callback.Callback(callback.State);
                }
                catch (Exception)
                {
                }
                finally
                {
                    Interlocked.Decrement(ref _inUseThreads);
                }
            }
        }
Esempio n. 5
0
 /// <summary>Resets the semaphore to the specified count. Should be used cautiously.</summary>
 public void Reset(int count)
 {
     using (TimedLock.Lock(this)) { _count = count; }
 }
Esempio n. 6
0
 /// <summary>
 /// Attempts to obtain a lock on the specified object for up to
 /// the specified timeout.
 /// </summary>
 /// <param name="o"></param>
 /// <param name="timeout"></param>
 /// <returns></returns>
 public static TimedLock Lock(object o, TimeSpan timeout)
 {
     Thread.BeginCriticalRegion();
     TimedLock tl = new TimedLock(o);
     if (!Monitor.TryEnter(o, timeout))
     {
         // Failed to acquire lock.
     #if DEBUG
         GC.SuppressFinalize(tl.leakDetector);
         throw new LockTimeoutException(o);
     #else
     throw new LockTimeoutException();
     #endif
     }
     return tl;
 }