container/timers/src/main/java/org/mobicents/slee/runtime/facilities/TimerFacilityImpl.java
public TimerID setTimer(ActivityContextInterface aci, Address address,
			long startTime, long period, int numRepetitions,
			TimerOptions timerOptions) throws NullPointerException,
			IllegalArgumentException, TransactionRolledbackLocalException,
			FacilityException {

		if (aci == null)
			throw new NullPointerException("Null ActivityContextInterface");
		if (startTime < 0)
			throw new IllegalArgumentException("startTime < 0");
		if (period <= 0)
			throw new IllegalArgumentException("period <= 0");
		if (timerOptions == null)
			throw new NullPointerException("Null TimerOptions");
		if (timerOptions.getTimeout() > period)
			throw new IllegalArgumentException("timeout > period"); 
		if (timerOptions.getTimeout() < this.getResolution())
			timerOptions.setTimeout(Math.min(period, this.getResolution()));
		
		if (period == Long.MAX_VALUE && numRepetitions == 1) {
			// non periodic value, the framework expects it to be negative instead
			period = -1;
		}
		
		// when numRepetitions == 0 the timer repeats infinitely or until
		// canceled
		if (numRepetitions < 0)
			throw new IllegalArgumentException("numRepetitions < 0");
		
		SleeTransactionManager txMgr = sleeContainer.getTransactionManager();
		boolean startedTx = txMgr.requireTransaction();

		TimerIDImpl timerID = new TimerIDImpl(sleeContainer.getUuidGenerator().createUUID());
		
		if (logger.isDebugEnabled()) {
			logger.debug("setTimer: timerID = "+timerID+" , startTime = " + startTime + " period = "
					+ period + " numRepetitions = " + numRepetitions
					+ " timeroptions =" + timerOptions);
		}

		// Attach to activity context
		org.mobicents.slee.container.activity.ActivityContextInterface aciImpl = (org.mobicents.slee.container.activity.ActivityContextInterface) aci;
		aciImpl.getActivityContext().attachTimer(timerID);
		
		// schedule timer task
		TimerFacilityTimerTaskData taskData = new TimerFacilityTimerTaskData(timerID, aciImpl.getActivityContext().getActivityContextHandle(), address, startTime, period, numRepetitions, timerOptions);
    	final TimerFacilityTimerTask task = new TimerFacilityTimerTask(taskData);
    	if(configuration.getTaskExecutionWaitsForTxCommitConfirmation()) {
    		final CountDownLatch countDownLatch = new CountDownLatch(1);
    		task.setCountDownLatch(countDownLatch);
    		TransactionalAction action = new TransactionalAction() {			
    			@Override
    			public void execute() {
    				countDownLatch.countDown();				
    			}
    		};
    		TransactionContext txContext = txMgr.getTransactionContext();
    		txContext.getAfterCommitActions().add(action);
    		txContext.getAfterRollbackActions().add(action);
    	}
		scheduler.schedule(task);				

		// If we started a tx for this operation, we commit it now
		if (startedTx) {
			try {
				txMgr.commit();
			} catch (Exception e) {
				throw new TransactionRolledbackLocalException(
						"Failed to commit transaction");
			}
		}

		return timerID;
	}
public TimerID setTimer(ActivityContextInterface aci, Address address,
			long startTime, long period, int numRepetitions,
			TimerOptions timerOptions) throws NullPointerException,
			IllegalArgumentException, TransactionRolledbackLocalException,
			FacilityException {

		if (aci == null)
			throw new NullPointerException("Null ActivityContextInterface");
		if (startTime < 0)
			throw new IllegalArgumentException("startTime < 0");
		if (period <= 0)
			throw new IllegalArgumentException("period <= 0");
		if (timerOptions == null)
			throw new NullPointerException("Null TimerOptions");
		if (timerOptions.getTimeout() > period)
			throw new IllegalArgumentException("timeout > period"); 
		if (timerOptions.getTimeout() < this.getResolution())
			timerOptions.setTimeout(Math.min(period, this.getResolution()));
		
		if (period == Long.MAX_VALUE && numRepetitions == 1) {
			// non periodic value, the framework expects it to be negative instead
			period = -1;
		}
		
		// when numRepetitions == 0 the timer repeats infinitely or until
		// canceled
		if (numRepetitions < 0)
			throw new IllegalArgumentException("numRepetitions < 0");
		
		SleeTransactionManager txMgr = sleeContainer.getTransactionManager();
		boolean startedTx = txMgr.requireTransaction();

		TimerIDImpl timerID = new TimerIDImpl(sleeContainer.getUuidGenerator().createUUID());
		
		if (logger.isDebugEnabled()) {
			logger.debug("setTimer: timerID = "+timerID+" , startTime = " + startTime + " period = "
					+ period + " numRepetitions = " + numRepetitions
					+ " timeroptions =" + timerOptions);
		}

		// Attach to activity context
		org.mobicents.slee.container.activity.ActivityContextInterface aciImpl = (org.mobicents.slee.container.activity.ActivityContextInterface) aci;
		aciImpl.getActivityContext().attachTimer(timerID);
		
		// schedule timer task
		TimerFacilityTimerTaskData taskData = new TimerFacilityTimerTaskData(timerID, aciImpl.getActivityContext().getActivityContextHandle(), address, startTime, period, numRepetitions, timerOptions);
    	final TimerFacilityTimerTask task = new TimerFacilityTimerTask(taskData);
    	if(configuration.getTaskExecutionWaitsForTxCommitConfirmation()) {
    		final CountDownLatch countDownLatch = new CountDownLatch(1);
    		task.setCountDownLatch(countDownLatch);
    		TransactionalAction action = new TransactionalAction() {			
    			@Override
    			public void execute() {
    				countDownLatch.countDown();				
    			}
    		};
    		TransactionContext txContext = txMgr.getTransactionContext();
    		txContext.getAfterCommitActions().add(action);
    		txContext.getAfterRollbackActions().add(action);
    	}
		scheduler.schedule(task);				

		// If we started a tx for this operation, we commit it now
		if (startedTx) {
			try {
				txMgr.commit();
			} catch (Exception e) {
				throw new TransactionRolledbackLocalException(
						"Failed to commit transaction");
			}
		}

		return timerID;
	}
/*
(non-Javadoc)
@see javax.slee.facilities.TimerFacility#setTimer(javax.slee.ActivityContextInterface, javax.slee.Address, long, long, int, javax.slee.facilities.TimerOptions)