Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   * 
   * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
   * 
   * The contents of this file are subject to the terms of either the GNU
   * General Public License Version 2 only ("GPL") or the Common Development
   * and Distribution License("CDDL") (collectively, the "License").  You
   * may not use this file except in compliance with the License. You can obtain
  * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
  * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
  * language governing permissions and limitations under the License.
  * 
  * When distributing the software, include this License Header Notice in each
  * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
  * Sun designates this particular file as subject to the "Classpath" exception
  * as provided by Sun in the GPL Version 2 section of the License file that
  * accompanied this code.  If applicable, add the following below the License
  * Header, with the fields enclosed by brackets [] replaced by your own
  * identifying information: "Portions Copyrighted [year]
  * [name of copyright owner]"
  * 
  * Contributor(s):
  * 
  * If you wish your version of this file to be governed by only the CDDL or
  * only the GPL Version 2, indicate your decision by adding "[Contributor]
  * elects to include this software in this distribution under the [CDDL or GPL
  * Version 2] license."  If you don't indicate a single choice of license, a
  * recipient has the option to distribute your version of this file under
  * either the CDDL, the GPL Version 2 or to extend the choice of license to
  * its licensees as provided above.  However, if you add GPL Version 2 code
  * and therefore, elected the GPL Version 2 license, then the option applies
  * only if the new code is made subject to such option by the copyright
  * holder.
  */
 
 /*
  * Copyright 2004-2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
 //----------------------------------------------------------------------------
 //
 // Module:      TimeoutManager.java
 //
 // Description: Transaction time-out manager.
 //
 // Product:     com.sun.jts.CosTransactions
 //
 // Author:      Simon Holdsworth
 //
 // Date:        March, 1997
 //
 // Copyright (c):   1995-1997 IBM Corp.
 //
 //   The source code for this program is not published or otherwise divested
 //   of its trade secrets, irrespective of what has been deposited with the
 //   U.S. Copyright Office.
 //
 //   This software contains confidential and proprietary information of
 //   IBM Corp.
 //----------------------------------------------------------------------------
 
 package com.sun.jts.CosTransactions;
 
 import java.util.*;
 
 import  org.omg.CosTransactions.*;
 
 import  com.sun.jts.trace.*;
 
This class records state for timing out transactions, and runs a thread which performs occasional checks to time out transactions.

Author(s):
Simon Holdsworth, IBM Corporation
Version:
0.01
See also:
 
 
 //----------------------------------------------------------------------------
 // CHANGE HISTORY
 //
 // Version By     Change Description
 //   0.01  SAJH   Initial implementation.
 //----------------------------------------------------------------------------
 
 class TimeoutManager {
    
Constants which define the types of timeout possible.
 
    static final int CANCEL_TIMEOUT   = 0;
    static final int NO_TIMEOUT       = 0;
    static final int ACTIVE_TIMEOUT   = 1;
    static final int IN_DOUBT_TIMEOUT = 2;

    
this attribute indicates whether initialisation has been started.
    private static boolean initialised = false;
    private static Hashtable     pendingTimeouts = new Hashtable();
    private static Hashtable     indoubtTimeouts = new Hashtable();
    private static TimeoutThread timeoutThread = null;
    private static boolean       timeoutActive = false;
    private static boolean       quiescing = false;
    private static boolean       isSetTimeout = false;
	/*
		Logger to log transaction messages
	*/  
    static Logger _logger = LogDomains.getLogger(TimeoutManager.class.);
    
Initialises the static state of the TimeoutManager class.

Parameters:
Returns:
See also:
    synchronized static void initialise() {
        // If already initialised, return immediately.
        if () {
            return;
        }
         = true;
        // Start the timeout thread.
        if (! &&  == null) {
           //  timeoutThread = new TimeoutThread();
           //  timeoutThread.start();
             = true;
        }
    }
    static synchronized void initSetTimeout() {
	   return;
         = true;
         = new TimeoutThread();
        .start();
    }

    
Sets the timeout for the transaction to the specified type and time in seconds.

If the type is none, the timeout for the transaction is cancelled, otherwise the current timeout for the transaction is modified to be of the new type and duration.

Parameters:
localTID The local identifier for the transaction.
timeoutType The type of timeout to establish.
seconds The length of the timeout.
Returns:
Indicates success of the operation.
See also:
     static boolean setTimeout(Long localTIDint timeoutType,
                                           int seconds) {
        boolean result = true;
        // Modify the timeout to the required type and value.
        if () {
            TimeoutInfo timeoutInfo = null;
            switch (timeoutType) {
            // If the new type is active or in_doubt, then create a
            // new TimeoutInfo if necessary, and set up the type and interval.
            case . :
		 if (!) {
		     initSetTimeout();
                 }
                 timeoutInfo = new TimeoutInfo();
                 timeoutInfo.expireTime  =
                    new Date().getTime() + seconds * 1000;
                 timeoutInfo.localTID    = localTID;
                 timeoutInfo.timeoutType = timeoutType;
                 .put(localTID,timeoutInfo);
                 break;
            case . :
		 if (!) {
		     initSetTimeout();
		     // isSetTimeout = true;
                 }
                timeoutInfo = new TimeoutInfo();
                timeoutInfo.expireTime  =
                    new Date().getTime() + seconds * 1000;
                timeoutInfo.localTID    = localTID;
                timeoutInfo.timeoutType = timeoutType;
                .put(localTID,timeoutInfo);
                break;
            // For any other type, remove the timeout if there is one.
            default:
		  break;
                   result = (.remove(localTID) != null);
		   if (!result)
                      result = (.remove(localTID) != null);
                    // If the transaction service is quiescing and
                    // there are no more pending timeouts,
                    // deactivate timeout and stop the timeout thread.
                    if ( && .isEmpty() && .isEmpty()) {
                        .stop();
                         = false;
                        // pendingTimeouts = null;
                    }
                break;
            }
        } else {
            // If timeouts are not active, just return false.
            result = false;
        }
        return result;
    }

    
Takes appropriate action for a timeout.

The type fo timeout is given, and the transaction represented by the Coordinator and its local identifier.

This method does not reference the TimeoutManager's state directly and so does not need to be synchronized.

Parameters:
localTID The local identifier for the transaction.
timeoutType The type of timeout.
Returns:
See also:
    static void timeoutCoordinator(Long localTIDint  timeoutType) {
        // Look up the Coordinator for the transaction.
        // If there is none, then the transaction has already gone.
        // Otherwise do something with the transaction.
        CoordinatorImpl coord = RecoveryManager.getLocalCoordinator(localTID);
        if (coord == null) {
            if(.isLoggable(.))
            {
                .logp(.,"TimeoutManager","timeoutCoordinator()",
		    "RecoveryManager.getLocalCoordinator() returned null,"+
		    "which means txn is done. Setting timeout type to CANCEL_TIMEOUT");
            }
            TimeoutManager.setTimeout(localTID,
                                      .,
                                      0);
        } else {
            synchronized (coord) {
                boolean[] isRoot = new boolean[1];
                switch (timeoutType) {
                // If active, then attempt to roll the transaction back.
                case . :
                    if(.isLoggable(.))
            	    {
                        .logp(.,"TimeoutManager","timeoutCoordinator()",
                                     "TimeoutManager.timeoutCoordinator():case ACTIVE_TIMEOUT"+
                                     "RecoveryManager.getLocalCoordinator() returned non-null,"+
                                     "which means txn is still around. Marking for Rollback the"+
                                     "transaction...: GTID is : " + 
                                     ((TopCoordinator)coord)...toString());
                    }
                    try {
                        // coord.rollback(true);
                        coord.rollback_only();
                    } catch (Throwable exc) {}
                    break;
                    // If in doubt, it must be a TopCoordinator.
                    // In that case replay_completion needs to be driven.
                    // This is done by telling the TopCoordinator to act as
                    // if in recovery.  The result is then used to
                    // determine what to do with the Coordinator.
                case . :
                    if(.isLoggable(.))
                    {
                        .logp(.,"TimeoutManager","timeoutCoordinator()",
                                     "TimeoutManager.timeoutCoordinator():case IN_DOUBT_TIMEOUT"+
                                     "RecoveryManager.getLocalCoordinator() returned non-null,"+
                                     "which means txn is still around. Invoking recover(boolean)"+
                                     "on TopCoordinator...: GTID is: "
                                     ((TopCoordinator)coord)...toString());
                    }
                    Status state = ((TopCoordinatorcoord).recover(isRoot);
                    if (state == Status.StatusUnknown) {
                    
                        // If the outcome is not currently known, we do
                        // nothing with the transaction, as we expect to
                        // eventually get an outcome from the parent.
                        // GDH put out warning in case this state
                        // continues for a long time.
                        .log(."jts.transaction_resync_from_orginator_failed");
                    } else if (state == Status.StatusCommitted) {
                        // For committed or rolled back, proceed with
                        // completion of the transaction, regardless of whether
                        // it is the root or a subordinate. This will
                        // result in the removal of the in-doubt timeout.
                        try {
                            ((TopCoordinator)coord).commit();
                            if (isRoot[0]) {
                                ((TopCoordinatorcoord).
                                    afterCompletion(state);
                            }
                        } catch (Throwable exc) {}
                    } else {
                        // By default, roll the transaction back.
                        try {
                            ((TopCoordinatorcoord).rollback(true);
                            if (isRoot[0]) {
                                ((TopCoordinatorcoord).
                                    afterCompletion(Status.StatusRolledBack);
                            }
                        } catch (Throwable exc) {}
                    }
                    break;
                default:
                    // Otherwise do nothing.
                    break;
                }
            }
        }
    }

    
Periodically checks the existing timeouts.

This is done to discover if any transactions have overrun their allotted time. Those which have are returned as an Enumeration.

Note that this method should not do anything that will cause a synchronized method in the RecoveryManager to be called, as this could cause a deadlock when RecoveryManager methods on other threads call setTimeout.

Parameters:
Returns:
The information for transactions which have timed out.
See also:
     static Enumeration checkTimeouts() {
        if (!)
           return null;
        Enumeration result = null;
        // When woken up, go through all current timeouts and identify those
        // which have expired.
        if ( && ((.size() != 0) || (.size() != 0))) {
            Vector timedOut = null;
            Enumeration timeouts = null;
          
            synchronized () {
                timeouts = .elements();
                while (timeouts.hasMoreElements()) {
                    TimeoutInfo timeoutInfo = (TimeoutInfo)timeouts.nextElement();
                    // For each timeout in the list, check whether it has expired.
                    // If so, look up the Coordinator and roll it back.
                    if (new Date().getTime() > timeoutInfo.expireTime) {
                       // Add the TimeoutInfo to the queue of
                       //those that have timed out.
                       if (timedOut == null) {
                           timedOut = new Vector();
                       }
                       timedOut.addElement(timeoutInfo);
                    }
               }
            }
	    synchronized () {
                timeouts = .elements();
                while (timeouts.hasMoreElements()) {
                    TimeoutInfo timeoutInfo = (TimeoutInfo)timeouts.nextElement();
                    // For each timeout in the list, check whether it has expired.
                    // If so, look up the Coordinator and roll it back.
                    if (new Date().getTime() > timeoutInfo.expireTime) {
                       // Add the TimeoutInfo to the queue of
                       //those that have timed out.
                       if (timedOut == null) {
                           timedOut = new Vector();
                       }
                       timedOut.addElement(timeoutInfo);
                    }
                }
            }
            // Enumerate the transactions which have timed out.
            if (timedOut != null) {
                result = timedOut.elements();
            }
           }
        // The remainder of the timeout processing is not carried out here
        // because we would get deadlocked with addCoordinator or
        // removeCoordinator that also update the timeout list.  Hence the
        // returned enumeration, which may be processed with
        // no concurrency control.
        return result;
    }

    

Returns:
a set of in-doubt transaction ids.
    static XID[] getInDoubtXids() {
        
       synchronized () {
        Vector inDoubtList = new Vector();
        
        Enumeration timeouts = .elements();
        while (timeouts.hasMoreElements()) {
            TimeoutInfo timeoutInfo = (TimeoutInfotimeouts.nextElement();
            // Look up the Coordinator for the transaction.
            // If there is none, then the transaction has already gone.
            // Otherwise do something with the transaction.
                
            CoordinatorImpl coord = 
                RecoveryManager.getLocalCoordinator(timeoutInfo.localTID);
                                
            if (coord != null) {
                XID xid = new XID();
                xid.copy(coord.getGlobalTID());
                inDoubtList.addElement(xid);
            }
        }
        
        return (XID[]) inDoubtList.toArray(new XID[] {});
       }
    }

    
Returns the amount of time left before the given transaction times out.

Parameters:
localTID The local identifier for the transaction.
Returns:
The time left. If there is no timeout for the transaction, this value will be negative. If the timeout period has been exceeded, this value will be zero.
See also:
    static long timeLeft(Long localTID) {
        TimeoutInfo timeoutInfo = (TimeoutInfo.get(localTID);
        if (timeoutInfo == null)
            timeoutInfo = (TimeoutInfo.get(localTID);
        long result = -1;
        if (timeoutInfo != null) {
            result = timeoutInfo.expireTime - new Date().getTime();
            if (result < 0) {
                result = 0;
            }
        }
        return result;
    }

    
Informs the TimeoutManager that the transaction service is being shut down. For immediate shutdown, the timeout thread is stopped and all timeout information discarded. For quiesce, the timeout thread is stopped when there are no running transactions left.

Parameters:
immediate Indicates whether to stop immediately.
Returns:
See also:
    static void shutdown(boolean immediate) {
        // For immediate, kill the timeout thread and throw
        // away all information. Also, if there are no pending
        // timeouts, there is nothing to quiesce so
        // shutdown immediately regardless.
        if (immediate ||
                 == null || .isEmpty()) {
            if ( != null) {
                .stop();
            }
            if ( != null) {
                .clear();
            }
             = null;
             = null;
             = false;
        } else {
             = true;
        }
    }

    
Reports the contents of the TimeoutManager tables. $Only required for debug.

Parameters:
immediate Indicates whether to stop immediately.
Returns:
See also:
    /*
    static void report() {
        // Report on pendingTimeouts.
        if (pendingTimeouts.size() > 0) {
			if(_logger.isLoggable(Level.FINER))
			{	
				_logger.logp(Level.FINER,"TimeoutManager","report()",
						"TimeoutManager.pendingTimeouts non-empty");
			}
            Enumeration keys = pendingTimeouts.keys();
            while (keys.hasMoreElements()) {
                Long localTID = (Long) keys.nextElement();
                TimeoutInfo timeInfo =
                    (TimeoutInfo) pendingTimeouts.get(localTID);
				if(_logger.isLoggable(Level.FINER))
				{
					_logger.logp(Level.FINER,"TimeoutManager","report()",
                			"localTid :"+localTID+" -> " + timeInfo);
				}
            }
        } else {
			if(_logger.isLoggable(Level.FINER))
			{
				_logger.logp(Level.FINER,"TimeoutManager","report()",
          		 		"TimeoutManager.pendingTimeouts empty");
			}
        }
    }
    */
This class records information for a timeout for a transaction.

Author(s):
Simon Holdsworth, IBM Corporation
Version:
0.1
See also:
//----------------------------------------------------------------------------
// CHANGE HISTORY
//
// Version By     Change Description
//   0.1   SAJH   Initial implementation.
//----------------------------------------------------------------------------
class TimeoutInfo extends Object {
    Long localTID = null;
    long expireTime = 0;
This class represents a thread on which the TimeoutManager can perform timeout checking.

Author(s):
Simon Holdsworth, IBM Corporation
Version:
0.01
See also:
//----------------------------------------------------------------------------
// CHANGE HISTORY
//
// Version By     Change Description
//   0.01  SAJH   Initial implementation.
//----------------------------------------------------------------------------
class TimeoutThread extends Thread {
    private int TIMEOUT_INTERVAL ;
    static Logger _logger = LogDomains.getLogger(TimeoutThread.class.);
    
TimeoutThread constructor.

This sets the thread name, and sets the thread to be a daemon thread so that it does not prevent the process from terminating.

Parameters:
Returns:
See also:
    TimeoutThread() {
        setName("JTS Timeout Thread"/*#Frozen*/);
        setDaemon(true);
        try{
            String timeout_interval = Configuration.getPropertyValue(.);
            if(timeout_interval!=null){
                = Integer.parseInt(timeout_interval);
                if(<10000)
                    =10000;
            }
            else{
                =10000;
            }
        }catch(Exception e){
            =10000;
        }
    }

    
Performs timeout checking on a regular basis (every ten seconds or so).

Parameters:
Returns:
See also:
    public void run() {
        try {
            while (true) {
                // Sleep for a while between checks.
                Thread.sleep();
                // Perform timeout checks, getting a list of timed-out
                // transactions.
                Enumeration timedOut = TimeoutManager.checkTimeouts();
                // Now we must go through the list, telling each
                // timed-out Coordinator to do something appropriate.
                if (timedOut != null) {
                    while (timedOut.hasMoreElements()) {
                        TimeoutInfo timeoutInfo =
                            (TimeoutInfotimedOut.nextElement();
                        // Look up the Coordinator and tell it to roll back
                        // if it still exists. Note that we rely on the
                        // Coordinator calling removeCoordinator when it
                        // has finished, which will remove the timeout from 
                        // the list, and remove other associations as well.
                        TimeoutManager.
                            timeoutCoordinator(timeoutInfo.localTID,
                                               timeoutInfo.timeoutType);
                    }
                }
            }
        } catch (InterruptedException exc) {
			.log(.,"jts.time_out_thread_stopped");
        }
    }
New to GrepCode? Check out our FAQ X