All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.objectweb.dream.synchro.ReadWriteLockFIFOImpl Maven / Gradle / Ivy

/**
 * Dream
 * Copyright (C) 2003-2004 INRIA Rhone-Alpes
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Contact : [email protected]
 *
 * Initial developer(s): Vivien Quema
 * Contributor(s):
 */

package org.objectweb.dream.synchro;


import org.objectweb.dream.dreamannotation.DreamComponent;
import org.objectweb.fractal.fraclet.annotation.annotations.Requires;

/**
 * FIFO implementation of the {@link ReadWriteLockItf}interface. Threads contend
 * in a First-in/First-out manner for access. This lock is NOT reentrant.
 * Current readers and writers should not try to re-obtain locks while holding
 * them
 * 

* Note: Inspired by Doug Lea's implementation. */ @DreamComponent(controllerDesc = "dreamUnstoppablePrimitive") public class ReadWriteLockFIFOImpl implements ReadWriteLockItf { //---------------------------------------------------------------------------- // Client Interface //---------------------------------------------------------------------------- /** * Fair SemaphoreItf serving as a kind of mutual exclusion lock. Writers acquire * on entry, and hold until rwlock exit. Readers acquire and release only * during entry (but are blocked from doing so if there is an active writer). */ @Requires(name = SemaphoreItf.ITF_NAME) protected SemaphoreItf entryLock; /** * Number of threads that have entered read lock. Note that this is never * reset to zero. Incremented only during acquisition of read lock while the * "entryLock" is held, but read elsewhere, so is declared volatile. */ protected volatile int readers; /** * Number of threads that have exited read lock. Note that this is never reset * to zero. Accessed only in code protected by synchronized(this). When * exreaders != readers, the rwlock is being used for reading. Else if the * entry lock is held, it is being used for writing (or in transition). Else * it is free. Note: To distinguish these states, we assume that fewer than * 2^32 reader threads can simultaneously execute. */ protected int exreaders; // --------------------------------------------------------------------------- // Implementation of the ReadWriteLockItf interface. // --------------------------------------------------------------------------- /** * @see ReadWriteLockItf#acquireRead() */ public void acquireRead() throws InterruptedException { entryLock.acquire(); ++readers; entryLock.release(); } /** * @see org.objectweb.dream.synchro.ReadWriteLockItf#releaseRead() */ public synchronized void releaseRead() { /* * If this is the last reader, notify a possibly waiting writer. Because * waits occur only when entry lock is held, at most one writer can be * waiting for this notification. Because increments to "readers" aren't * protected by "this" lock, the notification may be spurious (when an * incoming reader in in the process of updating the field), but at the * point tested in acquiring write lock, both locks will be held, thus * avoiding false alarms. And we will never miss an opportunity to send a * notification when it is actually needed. */ if (++exreaders == readers) { notify(); } } /** * @see org.objectweb.dream.synchro.ReadWriteLockItf#acquireWrite() */ public void acquireWrite() throws InterruptedException { // Acquiring entryLock first forces subsequent entering readers // (as well as writers) to block. entryLock.acquire(); // Only read "readers" once now before loop. We know it won't // change because we hold the entry lock needed to update it. int r = readers; try { synchronized (this) { while (exreaders != r) { wait(); } } } catch (InterruptedException ie) { entryLock.release(); throw ie; } } /** * @see org.objectweb.dream.synchro.ReadWriteLockItf#releaseWrite() */ public void releaseWrite() { entryLock.release(); } /** * @see org.objectweb.dream.synchro.ReadWriteLockItf#attemptRead(long) */ public boolean attemptRead(long msecs) throws InterruptedException { if (!entryLock.attempt(msecs)) { return false; } ++readers; entryLock.release(); return true; } /** * @see org.objectweb.dream.synchro.ReadWriteLockItf#attemptWrite(long) */ public boolean attemptWrite(long msecs) throws InterruptedException { long startTime = (msecs <= 0) ? 0 : System.currentTimeMillis(); if (!entryLock.attempt(msecs)) { return false; } int r = readers; try { synchronized (this) { while (exreaders != r) { long timeLeft = (msecs <= 0) ? 0 : msecs - (System.currentTimeMillis() - startTime); if (timeLeft <= 0) { entryLock.release(); return false; } wait(timeLeft); } return true; } } catch (InterruptedException ie) { entryLock.release(); throw ie; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy