static void monitorEnterSync(TObject o) { if (o.monitor == null) { o.monitor = new Monitor(); } if (o.monitor.owner == null) { o.monitor.owner = TThread.currentThread(); } else if (o.monitor.owner != TThread.currentThread()) { throw new IllegalStateException("Can't enter monitor from another thread synchronously"); } o.monitor.count++; }
static void monitorEnter(TObject o, int count) { if (o.monitor == null) { o.monitor = new Monitor(); } if (o.monitor.owner == null) { o.monitor.owner = TThread.currentThread(); } if (o.monitor.owner != TThread.currentThread()) { monitorEnterWait(o, count); } else { o.monitor.count += count; } }
@Sync static void monitorExit(final TObject o, int count) { if (o.isEmptyMonitor() || o.monitor.owner != TThread.currentThread()) { throw new TIllegalMonitorStateException(); } o.monitor.count -= count; if (o.monitor.count > 0) { return; } o.monitor.owner = null; if (!o.monitor.enteringThreads.isEmpty()) { Platform.postpone( () -> { if (o.isEmptyMonitor() || o.monitor.owner != null) { return; } if (!o.monitor.enteringThreads.isEmpty()) { o.monitor.enteringThreads.remove().run(); } }); } else { o.isEmptyMonitor(); } }
static void monitorExitSync(TObject o) { if (o.isEmptyMonitor() || o.monitor.owner != TThread.currentThread()) { throw new TIllegalMonitorStateException(); } if (--o.monitor.count == 0) { o.monitor.owner = null; } o.isEmptyMonitor(); }
private static class NotifyListenerImpl implements NotifyListener, TimerHandler, PlatformRunnable, TThreadInterruptHandler { final TObject obj; final AsyncCallback<Void> callback; final TThread currentThread = TThread.currentThread(); int timerId = -1; boolean expired; boolean performed; int lockCount; public NotifyListenerImpl(TObject obj, AsyncCallback<Void> callback, int lockCount) { this.obj = obj; this.callback = callback; this.lockCount = lockCount; } @Override public boolean expired() { boolean result = expired; expired = true; return result; } @Override public void onTimer() { if (!expired()) { run(); } } @Override public void run() { if (performed) { return; } performed = true; if (timerId >= 0) { Platform.killSchedule(timerId); timerId = -1; } TThread.setCurrentThread(currentThread); monitorEnterWait(obj, lockCount, callback); } @Override public void interrupted() { if (performed) { return; } performed = true; if (timerId >= 0) { Platform.killSchedule(timerId); timerId = -1; } Platform.postpone(() -> callback.error(new TInterruptedException())); } }
@Override public void run() { if (performed) { return; } performed = true; if (timerId >= 0) { Platform.killSchedule(timerId); timerId = -1; } TThread.setCurrentThread(currentThread); monitorEnterWait(obj, lockCount, callback); }
static void monitorEnterWait( final TObject o, final int count, final AsyncCallback<Void> callback) { final TThread thread = TThread.currentThread(); if (o.monitor == null) { o.monitor = new Monitor(); TThread.setCurrentThread(thread); o.monitor.count += count; callback.complete(null); return; } else if (o.monitor.owner == null) { o.monitor.owner = thread; TThread.setCurrentThread(thread); o.monitor.count += count; callback.complete(null); return; } o.monitor.enteringThreads.add( () -> { TThread.setCurrentThread(thread); o.monitor.owner = thread; o.monitor.count += count; callback.complete(null); }); }
public Monitor() { this.owner = TThread.currentThread(); enteringThreads = Platform.createQueue(); notifyListeners = Platform.createQueue(); }
static boolean holdsLock(TObject o) { return o.monitor != null && o.monitor.owner == TThread.currentThread(); }