001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.object.lockmanager.impl;
006:
007: import com.tc.logging.TCLogger;
008: import com.tc.logging.TCLogging;
009: import com.tc.object.lockmanager.api.WaitTimer;
010: import com.tc.object.lockmanager.api.WaitTimerCallback;
011: import com.tc.object.tx.WaitInvocation;
012: import com.tc.object.tx.WaitInvocation.Signature;
013: import com.tc.util.Assert;
014: import com.tc.util.TCTimerImpl;
015:
016: import java.util.Timer;
017: import java.util.TimerTask;
018:
019: /**
020: * Manages timed lock waits
021: *
022: * @author teck
023: */
024: public class WaitTimerImpl implements WaitTimer {
025: private static final TCLogger logger = TCLogging
026: .getLogger(WaitTimer.class);
027:
028: private final Timer timer = new TCTimerImpl(
029: "DSO Lock Object.wait() timer", true);
030: private boolean shutdown = false;
031:
032: //public WaitInvocation originalCall;
033:
034: public WaitTimerImpl() {
035: super ();
036: }
037:
038: public Timer getTimer() {
039: return timer;
040: }
041:
042: public TimerTask scheduleTimer(WaitTimerCallback callback,
043: WaitInvocation call, Object callbackObject) {
044: //this.originalCall = call;
045: final Signature signature = call.getSignature();
046:
047: if (signature == WaitInvocation.NO_ARGS) {
048: return null;
049: } else if (signature == WaitInvocation.LONG) {
050: if (call.getMillis() == 0) {
051: return null;
052: }
053: } else if (signature == WaitInvocation.LONG_INT) {
054: if ((call.getMillis() == 0) && (call.getNanos() == 0)) {
055: return null;
056: }
057: } else {
058: throw Assert
059: .failure("unknown wait signature: " + signature);
060: }
061:
062: final TimerTask rv = new TaskImpl(callback, call,
063: callbackObject);
064:
065: if (signature == WaitInvocation.LONG_INT) {
066: // logger.warn("Nanosecond granualarity not yet supported, adding 1ms to wait time instead");
067: timer.schedule(rv, call.getMillis() + 1);
068: } else {
069: timer.schedule(rv, call.getMillis());
070: }
071: call.mark();
072:
073: return rv;
074: }
075:
076: private static class TaskImpl extends TimerTask {
077:
078: private final WaitTimerCallback callback;
079: private final Object callbackObject;
080: private final WaitInvocation call;
081:
082: TaskImpl(WaitTimerCallback callback, WaitInvocation call,
083: Object callbackObject) {
084: this .callback = callback;
085: this .call = call;
086: this .callbackObject = callbackObject;
087: }
088:
089: public void run() {
090: try {
091: callback.waitTimeout(callbackObject);
092: } catch (Exception e) {
093: logger.error("Error processing wait timeout for "
094: + callbackObject, e);
095: }
096: }
097:
098: public boolean cancel() {
099: call.adjust();
100: return super .cancel();
101: }
102: }
103:
104: public synchronized void shutdown() {
105: if (shutdown)
106: return;
107: shutdown = true;
108: this.timer.cancel();
109: }
110:
111: }
|