Example #1
0
        protected internal override OwnerQueueElement <Thread> Acquire(LockedEntity key)
        {
            OwnerQueueElement <Thread> suggestion = new OwnerQueueElement <Thread>(currentThread());

            for ( ; ;)
            {
                OwnerQueueElement <Thread> owner = _locks.putIfAbsent(key, suggestion);
                if (owner == null)
                {                         // Our suggestion was accepted, we got the lock
                    return(suggestion);
                }

                Thread other = owner.Owner;
                if (other == currentThread())
                {                         // the lock has been handed to us (or we are re-entering), claim it!
                    owner.Count++;
                    return(owner);
                }

                // Make sure that we only add to the queue once, and if that addition fails (because the queue is dead
                // - i.e. has been removed from the map), retry form the top of the loop immediately.
                if (suggestion.Head == suggestion) // true if enqueue() has not been invoked (i.e. first time around)
                {                                  // otherwise it has already been enqueued, and we are in a spurious (or timed) wake up
                    if (!owner.Enqueue(suggestion))
                    {
                        continue;                                   // the lock has already been released, the queue is dead, retry!
                    }
                }
                parkNanos(key, _maxParkNanos);
            }
        }
Example #2
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Override @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") protected void release(LockedEntity key, OwnerQueueElement<Thread> ownerQueueElement)
        protected internal override void Release(LockedEntity key, OwnerQueueElement <Thread> ownerQueueElement)
        {
            if (0 == --ownerQueueElement.Count)
            {
                Thread nextThread;
                lock ( ownerQueueElement )
                {
                    nextThread = ownerQueueElement.Dequeue();
                    if (nextThread == currentThread())
                    {                                          // no more threads in the queue, remove this list
                        _locks.remove(key, ownerQueueElement); // done under synchronization to honour definition of 'dead'
                        nextThread = null;                     // to make unpark() a no-op.
                    }
                }
                unpark(nextThread);
            }
        }
Example #3
0
 /// <summary>
 /// Return true if the item was enqueued, or false if this LockOwner is dead.
 /// A dead LockOwner is no longer reachable from the map, and so no longer participates in the lock.
 /// </summary>
 internal bool Enqueue(OwnerQueueElement <OWNER> last)
 {
     lock (this)
     {
         if (Owner == default(OWNER))
         {
             return(false);                                 // don't enqueue into a dead queue
         }
         last.Head = this;
         last.Tail = this;
         Tail.tail = last;
         this.Tail = last;
         if (Head == this)
         {
             Head = last;
         }
         return(true);
     }
 }
Example #4
0
 internal OWNER Dequeue()
 {
     lock (this)
     {
         OwnerQueueElement <OWNER> first = this.Head;
         (this.Head = first.Tail).head = this;
         first.Tail = this;
         if (this.Head == this)
         {
             this.Tail = this;                                  // don't leave junk references around!
         }
         try
         {
             return(this.Owner = first.Owner);
         }
         finally
         {
             first.Owner = default(OWNER);                                    // mark 'first' as dead.
         }
     }
 }