001/* 002 * JGrapes Event Driven Framework 003 * Copyright (C) 2017-2026 Michael N. Lipp 004 * 005 * This program is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU Affero General Public License as published by 007 * the Free Software Foundation; either version 3 of the License, or 008 * (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, but 011 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 012 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public 013 * License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program; if not, see <http://www.gnu.org/licenses/>. 017 */ 018 019package org.jgrapes.core.internal; 020 021import java.time.Instant; 022import org.jgrapes.core.Components; 023 024/** 025 * The base class for completeion locks. 026 */ 027@SuppressWarnings({ "PMD.AbstractClassWithoutAbstractMethod", 028 "PMD.AvoidSynchronizedStatement" }) 029public abstract class CompletionLockBase { 030 031 private final EventBase<?> event; 032 private final long timeout; 033 private Components.Timer timer; 034 035 /** 036 * @param event the event to be locked 037 * @param timeout 038 */ 039 protected CompletionLockBase(EventBase<?> event, long timeout) { 040 this.event = event; 041 this.timeout = timeout; 042 event.addCompletionLock(this); 043 } 044 045 /* default */ long getTimeout() { 046 return timeout; 047 } 048 049 /** 050 * Removes this completion lock from the event that it was created for. 051 * 052 * This method may be invoked even if the completion lock has already 053 * been removed. This allows locks to be used for disjunctive wait. 054 */ 055 public void remove() { 056 event.removeCompletionLock(this); 057 } 058 059 /* default */ CompletionLockBase startTimer() { 060 if (timeout == 0) { 061 return this; 062 } 063 timer = Components.schedule(scheduledFor -> { 064 event.removeCompletionLock(this); 065 }, Instant.now().plusMillis(timeout)); 066 return this; 067 } 068 069 /* default */ void cancelTimer() { 070 synchronized (this) { 071 if (timer != null) { 072 timer.cancel(); 073 timer = null; 074 } 075 } 076 } 077}