| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.felix.shell.remote; |
| |
| /** |
| * Implements a reentrant lock. |
| * <p/> |
| * Public domain code. |
| */ |
| class ReentrantLock |
| { |
| protected Thread m_owner = null; |
| protected long m_holds = 0; |
| |
| public void acquire() throws InterruptedException |
| { |
| //log.debug("acquire()::" + Thread.currentThread().toString()); |
| if (Thread.interrupted()) |
| { |
| throw new InterruptedException(); |
| } |
| Thread caller = Thread.currentThread(); |
| synchronized (this) |
| { |
| if (caller == m_owner) |
| { |
| ++m_holds; |
| } |
| else |
| { |
| try |
| { |
| while (m_owner != null) |
| { |
| wait(); |
| } |
| m_owner = caller; |
| m_holds = 1; |
| } |
| catch (InterruptedException ex) |
| { |
| notify(); |
| throw ex; |
| } |
| } |
| } |
| }//acquire |
| |
| public boolean attempt(long msecs) throws InterruptedException |
| { |
| //log.debug("attempt()::" + Thread.currentThread().toString()); |
| if (Thread.interrupted()) |
| { |
| throw new InterruptedException(); |
| } |
| Thread caller = Thread.currentThread(); |
| synchronized (this) |
| { |
| if (caller == m_owner) |
| { |
| ++m_holds; |
| return true; |
| } |
| else if (m_owner == null) |
| { |
| m_owner = caller; |
| m_holds = 1; |
| return true; |
| } |
| else if (msecs <= 0) |
| { |
| return false; |
| } |
| else |
| { |
| long waitTime = msecs; |
| long start = System.currentTimeMillis(); |
| try |
| { |
| for (;;) |
| { |
| wait(waitTime); |
| if (caller == m_owner) |
| { |
| ++m_holds; |
| return true; |
| } |
| else if (m_owner == null) |
| { |
| m_owner = caller; |
| m_holds = 1; |
| return true; |
| } |
| else |
| { |
| waitTime = msecs - (System.currentTimeMillis() - start); |
| if (waitTime <= 0) |
| { |
| return false; |
| } |
| } |
| } |
| } |
| catch (InterruptedException ex) |
| { |
| notify(); |
| throw ex; |
| } |
| } |
| } |
| }//attempt |
| |
| /** |
| * Release the lock. |
| * |
| * @throws Error thrown if not current owner of lock |
| */ |
| public synchronized void release() |
| { |
| //log.debug("release()::" + Thread.currentThread().toString()); |
| if (Thread.currentThread() != m_owner) |
| { |
| throw new Error("Illegal Lock usage"); |
| } |
| |
| if (--m_holds == 0) |
| { |
| m_owner = null; |
| notify(); |
| } |
| }//release |
| |
| /** |
| * Release the lock N times. <code>release(n)</code> is |
| * equivalent in effect to: |
| * <pre> |
| * for (int i = 0; i < n; ++i) release(); |
| * </pre> |
| * <p/> |
| * |
| * @param n times the lock should be released. |
| * @throws Error thrown if not current owner of lock |
| * or has fewer than N holds on the lock |
| */ |
| public synchronized void release(long n) |
| { |
| if (Thread.currentThread() != m_owner || n > m_holds) |
| { |
| throw new Error("Illegal Lock usage"); |
| } |
| |
| m_holds -= n; |
| if (m_holds == 0) |
| { |
| m_owner = null; |
| notify(); |
| } |
| }//release |
| |
| /** |
| * Return the number of unreleased acquires performed |
| * by the current thread. |
| * Returns zero if current thread does not hold lock. |
| * |
| * @return the number of unreleased acquires performed by the owner thread. |
| */ |
| public synchronized long holds() |
| { |
| if (Thread.currentThread() != m_owner) |
| { |
| return 0; |
| } |
| return m_holds; |
| }//holds |
| }//class ReentrantLock |