Пример #1
0
  protected void flush(final Address new_coord) throws InterruptedException {
    // wait until all threads currently sending messages have returned (new threads after
    // flushing=true) will block
    // flushing is set to true in startFlusher()
    while (flushing && running) {
      if (in_flight_sends.get() == 0) break;
      Thread.sleep(100);
    }

    send_lock.lockInterruptibly();
    try {
      if (log.isTraceEnabled())
        log.trace(local_addr + ": coord changed from " + coord + " to " + new_coord);
      coord = new_coord;
      is_coord = Objects.equals(local_addr, coord);
      flushMessagesInForwardTable();
    } finally {
      if (log.isTraceEnabled()) log.trace(local_addr + ": flushing completed");
      flushing = false;
      ack_mode = true; // go to ack-mode after flushing
      num_acks = 0;
      send_cond.signalAll();
      send_lock.unlock();
    }
  }
Пример #2
0
  /**
   * Gets connection listener instance associated with transaction. This method is package protected
   * beacause it is intended only for test case use. Please don't use it in your production code.
   *
   * @param trackByTransaction transaction instance
   * @param mcp the managed connection pool associated with the desired connection listener
   * @return connection listener instance
   * @throws ResourceException Thrown if an error occurs
   */
  ConnectionListener getTransactionOldConnection(
      Transaction trackByTransaction, ManagedConnectionPool mcp) throws ResourceException {
    TransactionSynchronizationRegistry tsr = getTransactionSynchronizationRegistry();
    Lock lock = getLock();

    try {
      lock.lockInterruptibly();
    } catch (InterruptedException ie) {
      Thread.interrupted();

      throw new ResourceException(bundle.unableObtainLock(), ie);
    }
    try {
      // Already got one
      ConnectionListener cl = (ConnectionListener) tsr.getResource(mcp);
      if (cl != null) {
        if (trace)
          log.tracef("Previous connection tracked by transaction=%s tx=%s", cl, trackByTransaction);
        return cl;
      }

      return null;
    } finally {
      lock.unlock();
    }
  }
 public void f() {
   try {
     lock.lockInterruptibly();
   } catch (InterruptedException e) {
     System.err.println("ReentrantLockBlockTask is interrupted");
   }
   System.out.println("Exit from ReentrantLockBlockTask");
 }
Пример #4
0
 public void f() {
   try {
     lock.lockInterruptibly();
     System.out.println("lock acquired in f()");
   } catch (InterruptedException e) {
     System.out.println("Interrupted from lock acquisition in f()");
   }
 }
  @Override
  protected void handleMessageInternal(Message<?> message) throws Exception {
    Object correlationKey = correlationStrategy.getCorrelationKey(message);
    Assert.state(
        correlationKey != null,
        "Null correlation not allowed.  Maybe the CorrelationStrategy is failing?");

    if (logger.isDebugEnabled()) {
      logger.debug("Handling message with correlationKey [" + correlationKey + "]: " + message);
    }

    UUID groupIdUuid = UUIDConverter.getUUID(correlationKey);
    Lock lock = this.lockRegistry.obtain(groupIdUuid.toString());

    lock.lockInterruptibly();
    try {
      ScheduledFuture<?> scheduledFuture = this.expireGroupScheduledFutures.remove(groupIdUuid);
      if (scheduledFuture != null) {
        boolean canceled = scheduledFuture.cancel(true);
        if (canceled && logger.isDebugEnabled()) {
          logger.debug(
              "Cancel 'forceComplete' scheduling for MessageGroup with Correlation Key [ "
                  + correlationKey
                  + "].");
        }
      }
      MessageGroup messageGroup = messageStore.getMessageGroup(correlationKey);
      if (this.sequenceAware) {
        messageGroup = new SequenceAwareMessageGroup(messageGroup);
      }

      if (!messageGroup.isComplete() && messageGroup.canAdd(message)) {
        if (logger.isTraceEnabled()) {
          logger.trace("Adding message to group [ " + messageGroup + "]");
        }
        messageGroup = this.store(correlationKey, message);

        if (releaseStrategy.canRelease(messageGroup)) {
          Collection<Message<?>> completedMessages = null;
          try {
            completedMessages = this.completeGroup(message, correlationKey, messageGroup);
          } finally {
            // Always clean up even if there was an exception
            // processing messages
            this.afterRelease(messageGroup, completedMessages);
          }
        } else {
          scheduleGroupToForceComplete(messageGroup);
        }
      } else {
        discardMessage(message);
      }
    } finally {
      lock.unlock();
    }
  }
  private void scan() throws OperationFailedException {

    try {
      scanLock.lockInterruptibly();
    } catch (InterruptedException ie) {
      Thread.currentThread().interrupt();
      return;
    }
    try {
      if (scanEnabled) { // confirm the scan is still wanted

        log.tracef(
            "Scanning directory %s for deployment content changes",
            deploymentDir.getAbsolutePath());

        final List<ModelNode> updates = new ArrayList<ModelNode>();

        Map<String, File> foundDeployed = new HashMap<String, File>();
        Set<String> newlyAdded = new HashSet<String>();
        Set<String> registeredDeployments = getDeploymentNames();
        scanDirectory(deploymentDir, updates, foundDeployed, newlyAdded, registeredDeployments);

        // Add remove actions to the plan for anything we count as
        // deployed that we didn't find on the scan
        Set<String> toRemove = new HashSet<String>(deployed);
        toRemove.removeAll(foundDeployed.keySet());
        toRemove.removeAll(newlyAdded); // in case user removed the marker and added replacement
        for (String missing : toRemove) {
          updates.add(getUndeployOperation(missing));
          updates.add(getRemoveOperation(missing));
        }

        if (updates.size() > 0) {
          if (log.isDebugEnabled()) {
            for (ModelNode update : updates) {
              log.debugf("Deployment scan of [%s] found update action [%s]", deploymentDir, update);
            }
          }
          Operation composite = getCompositeUpdate(updates);
          ModelNode results = serverController.execute(composite);
          //                    System.out.println(composite);
          //                    System.out.println(results);
          // FIXME deal with result
        }

        // Throw away any found marker files that we didn't already know about
        Set<String> validFinds = cleanSpuriousMarkerFiles(foundDeployed);
        validFinds.addAll(newlyAdded);
        this.deployed = validFinds;

        log.tracef("Scan complete");
      }
    } finally {
      scanLock.unlock();
    }
  }
Пример #7
0
  /**
   * Gets new connection listener if necessary instance with transaction. This method is package
   * protected beacause it is intended only for test case use. Please don't use it in your
   * production code.
   *
   * @param trackByTransaction transaction instance
   * @param mcp pool instance
   * @param subject subject instance
   * @param cri connection request info
   * @return connection listener instance
   * @throws ResourceException ResourceException
   */
  ConnectionListener getTransactionNewConnection(
      Transaction trackByTransaction,
      ManagedConnectionPool mcp,
      Subject subject,
      ConnectionRequestInfo cri)
      throws ResourceException {
    // Need a new one for this transaction
    // This must be done outside the tx local lock, otherwise
    // the tx timeout won't work and get connection can do a lot of other work
    // with many opportunities for deadlocks.
    // Instead we do a double check after we got the transaction to see
    // whether another thread beat us to the punch.
    ConnectionListener cl = mcp.getConnection(subject, cri);
    if (trace)
      log.tracef(
          "Got connection from pool tracked by transaction=%s tx=%s", cl, trackByTransaction);

    TransactionSynchronizationRegistry tsr = getTransactionSynchronizationRegistry();
    Lock lock = getLock();
    try {
      lock.lockInterruptibly();
    } catch (InterruptedException ie) {
      Thread.interrupted();

      throw new ResourceException(bundle.unableObtainLock(), ie);
    }
    try {
      // Check we weren't racing with another transaction
      ConnectionListener other = (ConnectionListener) tsr.getResource(mcp);

      if (other != null) {
        mcp.returnConnection(cl, false);

        if (trace)
          log.tracef(
              "Another thread already got a connection tracked by transaction=%s tx=%s",
              other, trackByTransaction);

        cl = other;
      }

      // This is the connection for this transaction
      cl.setTrackByTx(true);
      tsr.putResource(mcp, cl);

      if (trace)
        log.tracef(
            "Using connection from pool tracked by transaction=%s tx=%s", cl, trackByTransaction);

      return cl;
    } finally {
      lock.unlock();
    }
  }
Пример #8
0
 public void insert(Thread thread) throws InterruptedException {
   lock.lockInterruptibly(); // 注意,如果需要正确中断等待锁的线程,必须将获取锁放在外面,然后将InterruptedException抛出
   try {
     System.out.println(thread.getName() + "得到了锁");
     long startTime = System.currentTimeMillis();
     for (; ; ) {
       if (System.currentTimeMillis() - startTime >= Integer.MAX_VALUE) break;
       // 插入数据
     }
   } finally {
     System.out.println(Thread.currentThread().getName() + "执行finally");
     lock.unlock();
     System.out.println(thread.getName() + "释放了锁");
   }
 }
  protected void forceComplete(MessageGroup group) {

    Object correlationKey = group.getGroupId();
    // UUIDConverter is no-op if already converted
    Lock lock = this.lockRegistry.obtain(UUIDConverter.getUUID(correlationKey).toString());
    boolean removeGroup = true;
    try {
      lock.lockInterruptibly();
      try {
        ScheduledFuture<?> scheduledFuture =
            this.expireGroupScheduledFutures.remove(UUIDConverter.getUUID(correlationKey));
        if (scheduledFuture != null) {
          boolean canceled = scheduledFuture.cancel(false);
          if (canceled && logger.isDebugEnabled()) {
            logger.debug("Cancel 'forceComplete' scheduling for MessageGroup [ " + group + "].");
          }
        }
        MessageGroup groupNow = group;
        /*
         * If the group argument is not already complete,
         * re-fetch it because it might have changed while we were waiting on
         * its lock. If the last modified timestamp changed, defer the completion
         * because the selection condition may have changed such that the group
         * would no longer be eligible. If the timestamp changed, it's a completely new
         * group and should not be reaped on this cycle.
         *
         * If the group argument is already complete, do not re-fetch.
         * Note: not all message stores provide a direct reference to its internal
         * group so the initial 'isComplete()` will only return true for those stores if
         * the group was already complete at the time of its selection as a candidate.
         *
         * If the group is marked complete, only consider it
         * for reaping if it's empty (and both timestamps are unaltered).
         */
        if (!group.isComplete()) {
          groupNow = this.messageStore.getMessageGroup(correlationKey);
        }
        long lastModifiedNow = groupNow.getLastModified();
        int groupSize = groupNow.size();
        if ((!groupNow.isComplete() || groupSize == 0)
            && group.getLastModified() == lastModifiedNow
            && group.getTimestamp() == groupNow.getTimestamp()) {
          if (groupSize > 0) {
            if (releaseStrategy.canRelease(groupNow)) {
              completeGroup(correlationKey, groupNow);
            } else {
              expireGroup(correlationKey, groupNow);
            }
            if (!this.expireGroupsUponTimeout) {
              afterRelease(groupNow, groupNow.getMessages(), true);
              removeGroup = false;
            }
          } else {
            /*
             * By default empty groups are removed on the same schedule as non-empty
             * groups. A longer timeout for empty groups can be enabled by
             * setting minimumTimeoutForEmptyGroups.
             */
            removeGroup =
                lastModifiedNow <= (System.currentTimeMillis() - this.minimumTimeoutForEmptyGroups);
            if (removeGroup && logger.isDebugEnabled()) {
              logger.debug("Removing empty group: " + correlationKey);
            }
          }
        } else {
          removeGroup = false;
          if (logger.isDebugEnabled()) {
            logger.debug(
                "Group expiry candidate ("
                    + correlationKey
                    + ") has changed - it may be reconsidered for a future expiration");
          }
        }
      } catch (MessageDeliveryException e) {
        removeGroup = false;
        if (logger.isDebugEnabled()) {
          logger.debug(
              "Group expiry candidate ("
                  + correlationKey
                  + ") has been affected by MessageDeliveryException - "
                  + "it may be reconsidered for a future expiration one more time");
        }
        throw e;
      } finally {
        try {
          if (removeGroup) {
            this.remove(group);
          }
        } finally {
          lock.unlock();
        }
      }
    } catch (InterruptedException ie) {
      Thread.currentThread().interrupt();
      logger.debug("Thread was interrupted while trying to obtain lock");
    }
  }
Пример #10
0
 @Override
 public void lockInterruptibly() throws InterruptedException {
   wrapped.lockInterruptibly();
 }
Пример #11
0
 /**
  * Acquire the given lock interruptibly, holding a reference to it for cleanup on thread
  * termination.
  *
  * @param lock the lock to acquire, released on thread termination
  * @throws InterruptedException if the lock acquisition is interrupted
  */
 public void lockInterruptibly(Lock lock) throws InterruptedException {
   assert Thread.currentThread() == getNativeThread();
   lock.lockInterruptibly();
   heldLocks.add(lock);
 }
Пример #12
0
  /** This method isn't private solely to allow a unit test in the same package to call it */
  void scan() {

    try {
      scanLock.lockInterruptibly();
    } catch (InterruptedException ie) {
      Thread.currentThread().interrupt();
      return;
    }
    try {
      if (scanEnabled) { // confirm the scan is still wanted
        log.tracef(
            "Scanning directory %s for deployment content changes",
            deploymentDir.getAbsolutePath());

        List<ScannerTask> scannerTasks = new ArrayList<ScannerTask>();

        final Set<String> registeredDeployments = getDeploymentNames();
        final Set<String> toRemove = new HashSet<String>(deployed.keySet());
        scanDirectory(deploymentDir, scannerTasks, registeredDeployments, toRemove);

        // Add remove actions to the plan for anything we count as
        // deployed that we didn't find on the scan
        for (String missing : toRemove) {
          // TODO -- minor -- this assumes the deployment was in the root deploymentDir,
          // not a child dir, and therefore puts the '.undeploying' file there
          File parent = deploymentDir;
          scannerTasks.add(new UndeployTask(missing, parent));
        }

        if (scannerTasks.size() > 0) {
          List<ModelNode> updates = new ArrayList<ModelNode>(scannerTasks.size());

          for (ScannerTask task : scannerTasks) {
            final ModelNode update = task.getUpdate();
            if (log.isDebugEnabled()) {
              log.debugf("Deployment scan of [%s] found update action [%s]", deploymentDir, update);
            }
            updates.add(update);
          }

          while (!updates.isEmpty()) {
            ModelNode composite = getCompositeUpdate(updates);
            final ModelNode results =
                serverController.execute(OperationBuilder.Factory.create(composite).build());
            final List<Property> resultList = results.get(RESULT).asPropertyList();
            final List<ModelNode> toRetry = new ArrayList<ModelNode>();
            final List<ScannerTask> retryTasks = new ArrayList<ScannerTask>();
            for (int i = 0; i < resultList.size(); i++) {
              final ModelNode result = resultList.get(i).getValue();
              final ScannerTask task = scannerTasks.get(i);
              final ModelNode outcome = result.get(OUTCOME);
              if (outcome.isDefined() && SUCCESS.equals(outcome.asString())) {
                task.handleSuccessResult();
              } else if (outcome.isDefined() && CANCELLED.equals(outcome.asString())) {
                toRetry.add(updates.get(i));
                retryTasks.add(task);
              } else {
                task.handleFailureResult(result);
              }
            }
            updates = toRetry;
            scannerTasks = retryTasks;
          }
        }
        log.tracef("Scan complete");
      }
    } finally {
      scanLock.unlock();
    }
  }