| /* |
| * Copyright (c) 2007, 2009, 2011, 2012 Eike Stepper (Berlin, Germany) and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Eike Stepper - initial API and implementation |
| */ |
| package org.eclipse.net4j.util.concurrent; |
| |
| import org.eclipse.net4j.util.WrappedException; |
| |
| import java.util.concurrent.Callable; |
| import java.util.concurrent.TimeUnit; |
| import java.util.concurrent.TimeoutException; |
| import java.util.concurrent.locks.Lock; |
| import java.util.concurrent.locks.ReentrantReadWriteLock; |
| |
| /** |
| * @author Eike Stepper |
| */ |
| public class RWLock extends ReentrantReadWriteLock |
| { |
| private static final long serialVersionUID = 1L; |
| |
| private long timeoutMillis; |
| |
| public RWLock(long timeoutMillis) |
| { |
| this.timeoutMillis = timeoutMillis; |
| } |
| |
| public RWLock(long timeoutMillis, boolean fair) |
| { |
| super(fair); |
| this.timeoutMillis = timeoutMillis; |
| } |
| |
| public <V> V read(Callable<V> callable) |
| { |
| return call(callable, readLock(), timeoutMillis); |
| } |
| |
| public void read(Runnable runnable) |
| { |
| run(runnable, readLock(), timeoutMillis); |
| } |
| |
| public <V> V write(Callable<V> callable) |
| { |
| return call(callable, writeLock(), timeoutMillis); |
| } |
| |
| public void write(Runnable runnable) |
| { |
| run(runnable, writeLock(), timeoutMillis); |
| } |
| |
| public static <V> V call(Callable<V> callable, Lock lock, long timeoutMillis) |
| { |
| try |
| { |
| boolean locked = lock.tryLock(timeoutMillis, TimeUnit.MILLISECONDS); |
| if (locked) |
| { |
| try |
| { |
| return callable.call(); |
| } |
| finally |
| { |
| lock.unlock(); |
| } |
| } |
| |
| throw new TimeoutException("Acquisition of lock timed out after " + timeoutMillis + " millis"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| catch (Exception ex) |
| { |
| throw WrappedException.wrap(ex); |
| } |
| } |
| |
| public static void run(Runnable runnable, Lock lock, long timeoutMillis) |
| { |
| try |
| { |
| boolean locked = lock.tryLock(timeoutMillis, TimeUnit.MILLISECONDS); |
| if (locked) |
| { |
| try |
| { |
| runnable.run(); |
| } |
| finally |
| { |
| lock.unlock(); |
| } |
| } |
| else |
| { |
| throw new TimeoutException("Acquisition of lock timed out after " + timeoutMillis + " millis"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| catch (Exception ex) |
| { |
| throw WrappedException.wrap(ex); |
| } |
| } |
| } |