View Javadoc
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  }