Package org.infinispan.remoting.transport.jgroups

Source Code of org.infinispan.remoting.transport.jgroups.JGroupsDistSync

/*
* JBoss, Home of Professional Open Source
* Copyright 2009 Red Hat Inc. and/or its affiliates and other
* contributors as indicated by the @author tags. All rights reserved.
* See the copyright.txt in the distribution for a full listing of
* individual contributors.
*
* This 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.1 of
* the License, or (at your option) any later version.
*
* This software 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 software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.infinispan.remoting.transport.jgroups;

import net.jcip.annotations.ThreadSafe;
import org.infinispan.remoting.transport.DistributedSync;
import org.infinispan.util.concurrent.ConcurrentHashSet;
import org.infinispan.util.concurrent.ReclosableLatch;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import static java.lang.String.format;
import static java.lang.Thread.currentThread;
import static org.infinispan.util.Util.prettyPrintTime;

/**
* A DistributedSync based on JGroups' FLUSH protocol
*
* @author Manik Surtani
* @since 4.0
*/
@ThreadSafe
public class JGroupsDistSync implements DistributedSync {

   private final ReentrantReadWriteLock processingLock = new ReentrantReadWriteLock();
   private final ReclosableLatch flushBlockGate = new ReclosableLatch(true);
   private final AtomicInteger flushBlockGateCount = new AtomicInteger(0);
   private final AtomicInteger flushWaitGateCount = new AtomicInteger(0);
   private final ReclosableLatch flushWaitGate = new ReclosableLatch(false);
   private static final Log log = LogFactory.getLog(JGroupsDistSync.class);
   private static final boolean trace = log.isTraceEnabled();

   private final ConcurrentHashSet<Thread> debugReadLockHolders = new ConcurrentHashSet<Thread>();

   public SyncResponse blockUntilAcquired(long timeout, TimeUnit timeUnit) throws TimeoutException {
      int initState = flushWaitGateCount.get();
      try {
         if (!flushWaitGate.await(timeout, timeUnit))
            throw new TimeoutException("Timed out waiting for a cluster-wide sync to be acquired. (timeout = " + prettyPrintTime(timeout) + ")");
      } catch (InterruptedException ie) {
         currentThread().interrupt();
      }

      return initState == flushWaitGateCount.get() ? SyncResponse.STATE_PREEXISTED : SyncResponse.STATE_ACHIEVED;

   }

   public SyncResponse blockUntilReleased(long timeout, TimeUnit timeUnit) throws TimeoutException {
      int initState = flushBlockGateCount.get();
      try {
         if (!flushBlockGate.await(timeout, timeUnit))
            throw new TimeoutException("Timed out waiting for a cluster-wide sync to be released. (timeout = " + prettyPrintTime(timeout) + ")");
      } catch (InterruptedException ie) {
         currentThread().interrupt();
      }


      return initState == flushWaitGateCount.get() ? SyncResponse.STATE_PREEXISTED : SyncResponse.STATE_ACHIEVED;
   }

   public void acquireSync() {
      flushBlockGate.close();
      flushWaitGateCount.incrementAndGet();
      flushWaitGate.open();
   }

   public void releaseSync() {
      flushWaitGate.close();
      flushBlockGateCount.incrementAndGet();
      flushBlockGate.open();
   }

   public void acquireProcessingLock(boolean exclusive, long timeout, TimeUnit timeUnit) throws TimeoutException {
      Lock lock = exclusive ? processingLock.writeLock() : processingLock.readLock();
      try {
         if (!lock.tryLock(timeout, timeUnit)) {
            if (exclusive) log.debugf("Failed to acquire exclusive processing lock. Read lock holders are %s", debugReadLockHolders);
            throw new TimeoutException(format("%s could not obtain %s processing lock after %s.  Locks in question are %s and %s",
                  currentThread().getName(), exclusive ? "exclusive" : "shared", prettyPrintTime(timeout, timeUnit),
                  processingLock.readLock(), processingLock.writeLock()));
         }
         if (log.isDebugEnabled() && !exclusive) debugReadLockHolders.add(currentThread());
      } catch (InterruptedException ie) {
         currentThread().interrupt();
      }
   }

   public void releaseProcessingLock(boolean exclusive) {
      try {
         if (exclusive) {
            processingLock.writeLock().unlock();
         } else {
            processingLock.readLock().unlock();
            if (log.isDebugEnabled()) debugReadLockHolders.remove(currentThread());
         }
      } catch (IllegalMonitorStateException imse) {
         if (trace) log.trace("Did not own lock!");
      }
   }
}
TOP

Related Classes of org.infinispan.remoting.transport.jgroups.JGroupsDistSync

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.