1 /*
2 * junixsocket
3 *
4 * Copyright 2009-2026 Christian Kohlschütter
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18 package org.newsclub.net.unix.memory;
19
20 import java.io.Closeable;
21 import java.io.IOException;
22 import java.util.function.Supplier;
23
24 /**
25 * A generic Futex interface.
26 *
27 * @author Christian Kohlschütter
28 */
29 interface Futex extends Closeable {
30 /**
31 * Tries to wait on the futex, if and as long as it has the value specified in {@code ifValue},
32 * for the given amount in milliseconds, or, if {@code timeoutMillis} is 0, for as long as the
33 * condition holds. Sporadic wakeups (with a return value of {@code false}) may occur.
34 *
35 * @param ifValue The expected value for this wait.
36 * @param timeoutMillis The timeout, in milliseconds, or 0 for "undetermined".
37 * @return {@code true} if the wait was successful (the value changed or {@link #tryWake(boolean)}
38 * was called), {@code false} otherwise.
39 * @throws IOException on error.
40 */
41 boolean tryWait(int ifValue, int timeoutMillis) throws IOException;
42
43 /**
44 * Tries to wake waiting threads on the futex. If {@code wakeAll} is true, then all waiting
45 * threads are woken up, if not, then only one is woken up.
46 *
47 * @param wakeAll {@code true} if all waiting threads should be woken.
48 * @return {@code true} if we definitely woke some; {@code false} may indicate "we don't know".
49 * @throws IOException on error.
50 */
51 boolean tryWake(boolean wakeAll) throws IOException;
52
53 /**
54 * Tries to wake any/all waiters on the futex for up to the given amount of time (in
55 * {@code timeoutMillis}), intermittently pausing for {@code pauseMillis}) to give other threads
56 * time to react, for as long as the timeout is not expired and {@code keepGoing} supplies
57 * {@code true}.
58 *
59 * @param wakeAll {@code true} if all waiting threads should be woken.
60 * @param timeoutMillis The maximum amount of time (in milliseconds) to try.
61 * @param pauseMillis While trying, pause this amount of milliseconds to give other threads time
62 * to react.
63 * @param keepGoing Keeps going unless this returns {@code true} or the timeout elapses.
64 * @return {@code false} If the timeout elapsed without either {@link #tryWake(boolean)} returns
65 * {@code true} or {@code keepGoing} returns {@code false}.
66 * @throws IOException on error.
67 * @throws InterruptedException on interrupt.
68 */
69 default boolean tryWakeWithTimeout(boolean wakeAll, int timeoutMillis, int pauseMillis,
70 Supplier<Boolean> keepGoing) throws IOException, InterruptedException {
71 long end = System.currentTimeMillis() + timeoutMillis;
72 while (keepGoing.get() && !tryWake(wakeAll)) {
73 if (System.currentTimeMillis() >= end) {
74 return false;
75 } else {
76 Thread.sleep(pauseMillis);
77 }
78 }
79 return true;
80 }
81
82 /**
83 * Returns {@code true} if this {@link Futex} has been closed.
84 *
85 * @return {@code true} if closed.
86 */
87 boolean isClosed();
88
89 /**
90 * Reports if this {@link Futex} can safely be accessed from multiple processes, or not. The
91 * actual way of accessing this {@link Futex} is unspecified, but typically this is coordinated
92 * via {@link SharedMemory}.
93 * <p>
94 * The value returned is constant.
95 *
96 * @return {@code true} if inter-process access is permitted.
97 */
98 boolean isInterProcess();
99 }