9
0
mirror of https://github.com/Dreeam-qwq/Gale.git synced 2025-12-22 08:19:31 +00:00
Files
Gale/patches/server/0140-Thread-safety-annotations.patch
2022-12-26 07:32:09 +01:00

367 lines
16 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martijn Muijsers <martijnmuijsers@live.nl>
Date: Sun, 4 Dec 2022 14:42:26 +0100
Subject: [PATCH] Thread-safety annotations
License: AGPL-3.0 (https://www.gnu.org/licenses/agpl-3.0.html)
Gale - https://galemc.org
diff --git a/src/main/java/org/galemc/gale/executor/annotation/Access.java b/src/main/java/org/galemc/gale/executor/annotation/Access.java
new file mode 100644
index 0000000000000000000000000000000000000000..d07f68ff73a368c8f0da56152021a95474a601ca
--- /dev/null
+++ b/src/main/java/org/galemc/gale/executor/annotation/Access.java
@@ -0,0 +1,39 @@
+// Gale - thread-safety annotations
+
+package org.galemc.gale.executor.annotation;
+
+/**
+ * An enum to distinguish the type of field access that a thread-safety annotation describes.
+ *
+ * @author Martijn Muijsers under AGPL-3.0
+ */
+public enum Access {
+
+ /**
+ * If the annotation is applied to a field, it holds for access to the field's value.
+ * <br>
+ * This may or may not extend to conceptual access rather than field value access: for instance, if the field is
+ * a list, accessing elements of the list, or if the field is an object reference,
+ * accessing field of that reference.
+ */
+ READ,
+ /**
+ * If the annotation is applied to a field, it holds for modifications made to the field.
+ * <br>
+ * This may or may not extend to conceptual modifications rather than setting the field value: for instance,
+ * if the field is a list, adding elements to the list, or if the field is an object reference,
+ * setting fields of that reference.
+ */
+ WRITE,
+ /**
+ * Both {@link #READ} and {@link #WRITE}: if the annotation is applied to a field, it holds for both access to
+ * the field's value, as well as modifications made to the field.
+ * <br>
+ * This may or may not extend to conceptual access and/or modifications.
+ *
+ * @see #READ
+ * @see #WRITE
+ */
+ READ_WRITE;
+
+}
diff --git a/src/main/java/org/galemc/gale/executor/annotation/Guarded.java b/src/main/java/org/galemc/gale/executor/annotation/Guarded.java
new file mode 100644
index 0000000000000000000000000000000000000000..37365e1fd6042dc721d875021b4092410f095ca5
--- /dev/null
+++ b/src/main/java/org/galemc/gale/executor/annotation/Guarded.java
@@ -0,0 +1,45 @@
+// Gale - thread-safety annotations
+
+package org.galemc.gale.executor.annotation;
+
+import org.galemc.gale.executor.annotation.thread.ThreadRestricted;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * An annotation primarily for fields, identifying fields that can only be accessed and/or modified when the
+ * described lock is acquired by the current thread.
+ * <br>
+ * When applied to a method, this annotation indicates that calls to the method must happen only when the described
+ * lock is acquired by the current thread. This annotation does NOT mean that the method will acquire the lock
+ * in its method body.
+ * <br>
+ * When applied to a class, this annotation indicates it holds for all methods and fields, both instance and static,
+ * belonging to the class, or any superclass thereof, or any inner or statically nested class of the class or
+ * any superclass thereof, except for any cases where a conflicting annotation with a smaller scope is also present.
+ *
+ * @author Martijn Muijsers under AGPL-3.0
+ */
+@Documented
+@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
+public @interface Guarded {
+
+ /**
+ * @return A description of the lock that the annotated element is guarded by: typically a Javadoc reference
+ * to a field, e.g. "#statusLock".
+ */
+ String value();
+
+ /**
+ * @see ThreadRestricted#fieldAccess()
+ */
+ Access fieldAccess() default Access.READ_WRITE;
+
+ /**
+ * @return A description of in what scenario the lock described by this annotation is not needed to be acquired.
+ */
+ String except() default "";
+
+}
diff --git a/src/main/java/org/galemc/gale/executor/annotation/PotentiallyBlocking.java b/src/main/java/org/galemc/gale/executor/annotation/PotentiallyBlocking.java
new file mode 100644
index 0000000000000000000000000000000000000000..71f26852c96dea34ea07efe07f834f8262509957
--- /dev/null
+++ b/src/main/java/org/galemc/gale/executor/annotation/PotentiallyBlocking.java
@@ -0,0 +1,39 @@
+// Gale - thread-safety annotations
+
+package org.galemc.gale.executor.annotation;
+
+import org.galemc.gale.executor.thread.BaseThread;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * An annotation primarily for methods, identifying methods that may block the thread.
+ * <br>
+ * When applied to a class, this annotation indicates it holds for all methods, both instance and static,
+ * belonging to the class, or any superclass thereof, or any inner or statically nested class of the class or
+ * any superclass thereof, except for any cases where a conflicting annotation with a smaller scope is also present.
+ * <br>
+ * In a method annotated with {@link PotentiallyBlocking}, fields and methods annotated with
+ * {@link PotentiallyBlocking}, {@link PotentiallyYielding} or {@link YieldFree} may all be used.
+ * <br>
+ * Methods that are potentially blocking, including those annotated with {@link PotentiallyBlocking}, must never
+ * be called on a {@link BaseThread}.
+ *
+ * @author Martijn Muijsers under AGPL-3.0
+ */
+@Documented
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface PotentiallyBlocking {
+
+ /**
+ * @return A description of when the described method is potentially blocking.
+ * When describing conditions, the description should make clear whether those conditions must hold for the method
+ * to block, or make blocking more likely, or will certainly lead the method to block, or preclude the method
+ * from blocking, or have some other relation to the expectation of blocking.
+ * If left empty (as default), the method potentially blocks under any conditions.
+ */
+ String value() default "";
+
+}
diff --git a/src/main/java/org/galemc/gale/executor/annotation/PotentiallyYielding.java b/src/main/java/org/galemc/gale/executor/annotation/PotentiallyYielding.java
new file mode 100644
index 0000000000000000000000000000000000000000..e87ee2612348fc559b21256cc7cadfc684f01f8e
--- /dev/null
+++ b/src/main/java/org/galemc/gale/executor/annotation/PotentiallyYielding.java
@@ -0,0 +1,35 @@
+// Gale - thread-safety annotations
+
+package org.galemc.gale.executor.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * An annotation primarily for methods, identifying methods that do not block, but may yield to other tasks
+ * under certain circumstances, such as when attempting to acquire a {@link YieldingLock}.
+ * <br>
+ * When applied to a class, this annotation indicates it holds for all methods, both instance and static,
+ * belonging to the class, or any superclass thereof, or any inner or statically nested class of the class or
+ * any superclass thereof, except for any cases where a conflicting annotation with a smaller scope is also present.
+ * <br>
+ * In a method annotated with {@link PotentiallyYielding}, the only methods that can be called are those
+ * annotated with {@link PotentiallyYielding} or {@link YieldFree}.
+ *
+ * @author Martijn Muijsers under AGPL-3.0
+ */
+@Documented
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface PotentiallyYielding {
+
+ /**
+ * @return A description of when the described method is potentially yielding.
+ * When describing conditions, the description should make clear whether those conditions must hold for the method
+ * to yield, or make yielding more likely, or will certainly lead the method to yield, or preclude the method
+ * from yielding, or have some other relation to the expectation of yielding.
+ * If left empty (as default), the method potentially yields under any conditions.
+ */
+ String value() default "";
+
+}
diff --git a/src/main/java/org/galemc/gale/executor/annotation/YieldFree.java b/src/main/java/org/galemc/gale/executor/annotation/YieldFree.java
new file mode 100644
index 0000000000000000000000000000000000000000..dc660a3fb401fc3cb713a4556468fd6686e29c51
--- /dev/null
+++ b/src/main/java/org/galemc/gale/executor/annotation/YieldFree.java
@@ -0,0 +1,27 @@
+// Gale - thread-safety annotations
+
+package org.galemc.gale.executor.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+import java.util.concurrent.locks.Lock;
+
+/**
+ * An annotation primarily for methods, identifying methods that do not block, and are yield-free, i.e. that never
+ * yield to other tasks. Such a method may still speculatively attempt to acquire blocking locks or yielding locks,
+ * e.g. using {@link Lock#tryLock}, under the condition that failure to acquire the lock does not cause blocking
+ * or yielding.
+ * <br>
+ * When applied to a class, this annotation indicates it holds for all methods, both instance and static,
+ * belonging to the class, or any superclass thereof, or any inner or statically nested class of the class or
+ * any superclass thereof, except for any cases where a conflicting annotation with a smaller scope is also present.
+ * <br>
+ * In a method annotated with {@link PotentiallyYielding}, the only methods that can be called are those
+ * annotated with {@link YieldFree}.
+ *
+ * @author Martijn Muijsers under AGPL-3.0
+ */
+@Documented
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface YieldFree {}
diff --git a/src/main/java/org/galemc/gale/executor/annotation/thread/AnyThreadSafe.java b/src/main/java/org/galemc/gale/executor/annotation/thread/AnyThreadSafe.java
new file mode 100644
index 0000000000000000000000000000000000000000..f9f4deeb3edce30a8052172c0b2be905bbd90844
--- /dev/null
+++ b/src/main/java/org/galemc/gale/executor/annotation/thread/AnyThreadSafe.java
@@ -0,0 +1,42 @@
+// Gale - thread-safety annotations
+
+package org.galemc.gale.executor.annotation.thread;
+
+import org.galemc.gale.executor.annotation.Access;
+import org.galemc.gale.executor.annotation.PotentiallyBlocking;
+import org.galemc.gale.executor.annotation.PotentiallyYielding;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * An annotation primarily for methods, identifying methods that can safely called from any thread,
+ * including but not limited to threads that are yielding.
+ * <br>
+ * When applied to a field, this annotation indicates that the field can be safely arbitrarily accessed and/or modified
+ * from any thread.
+ * <br>
+ * When applied to a class, this annotation indicates it holds for all methods and fields, both instance and static,
+ * belonging to the class, or any superclass thereof, or any inner or statically nested class of the class or
+ * any superclass thereof, except for any cases where a conflicting annotation with a smaller scope is also present.
+ * <br>
+ * In a method annotated with {@link AnyThreadSafe}, the only fields and methods that can be used are those
+ * annotated with {@link AnyThreadSafe}, unless extra safety guarantees are checked or explicitly provided.
+ * Use of methods that are potentially yielding (at least those annotated with {@link PotentiallyYielding}, but also
+ * those annotated with {@link PotentiallyBlocking} that potentially yield) is discouraged,
+ * because some threads cannot yield, and must block instead,
+ * leading to context switches where none may be expected.
+ *
+ * @author Martijn Muijsers under AGPL-3.0
+ */
+@Documented
+@Target({ElementType.METHOD, ElementType.TYPE, ElementType.FIELD})
+public @interface AnyThreadSafe {
+
+ /**
+ * @see ThreadRestricted#fieldAccess()
+ */
+ Access value() default Access.READ_WRITE;
+
+}
diff --git a/src/main/java/org/galemc/gale/executor/annotation/thread/ThisThreadOnly.java b/src/main/java/org/galemc/gale/executor/annotation/thread/ThisThreadOnly.java
new file mode 100644
index 0000000000000000000000000000000000000000..2544ec2ef1d401696d61c6c75b72f79ffbb21e87
--- /dev/null
+++ b/src/main/java/org/galemc/gale/executor/annotation/thread/ThisThreadOnly.java
@@ -0,0 +1,32 @@
+// Gale - thread-safety annotations
+
+package org.galemc.gale.executor.annotation.thread;
+
+import org.galemc.gale.executor.annotation.Access;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * An annotation primarily for methods, identifying methods that can only be called from the
+ * enclosing {@link Thread} instance.
+ * <br>
+ * This annotation can also be used on fields, similar to {@link ThreadRestricted}.
+ * <br>
+ * This annotation can only be used within {@link Thread} or subclasses thereof.
+ *
+ * @see ThreadRestricted
+ *
+ * @author Martijn Muijsers under AGPL-3.0
+ */
+@Documented
+@Target({ElementType.METHOD, ElementType.FIELD})
+public @interface ThisThreadOnly {
+
+ /**
+ * @see ThreadRestricted#fieldAccess()
+ */
+ Access value() default Access.READ_WRITE;
+
+}
diff --git a/src/main/java/org/galemc/gale/executor/annotation/thread/ThreadRestricted.java b/src/main/java/org/galemc/gale/executor/annotation/thread/ThreadRestricted.java
new file mode 100644
index 0000000000000000000000000000000000000000..4a9df03bfa4d683ad32496a20b19ab53015e8d8f
--- /dev/null
+++ b/src/main/java/org/galemc/gale/executor/annotation/thread/ThreadRestricted.java
@@ -0,0 +1,51 @@
+// Gale - thread-safety annotations
+
+package org.galemc.gale.executor.annotation.thread;
+
+import org.galemc.gale.executor.annotation.Access;
+import org.galemc.gale.executor.annotation.PotentiallyBlocking;
+import org.galemc.gale.executor.annotation.PotentiallyYielding;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * An annotation primarily for methods, identifying methods that can only be called on a specific thread or
+ * set of threads, as described by the given description.
+ * <br>
+ * When applied to a field, this annotation indicates that the field can only be accessed and/or modified from the
+ * described specific thread or set of threads.
+ * <br>
+ * When applied to a class, this annotation indicates it holds for all methods and fields, both instance and static,
+ * belonging to the class, or any superclass thereof, or any inner or statically nested class of the class or
+ * any superclass thereof, except for any cases where a conflicting annotation with a smaller scope is also present.
+ * <br>
+ * In a method annotated with {@link ThreadRestricted}, the only fields and methods that can be used are those
+ * annotated with {@link ThreadRestricted} that have a similar or stricter condition,
+ * unless extra safety guarantees are checked or explicitly provided.
+ * Use of methods that are potentially yielding (at least those annotated with {@link PotentiallyYielding}, but also
+ * those annotated with {@link PotentiallyBlocking} that potentially yield), when the restriction allows for threads
+ * that are not yielding, is discouraged, because some threads cannot yield, and must block instead,
+ * leading to context switches where none may be expected.
+ *
+ * @author Martijn Muijsers under AGPL-3.0
+ */
+@Documented
+@Target({ElementType.METHOD, ElementType.TYPE, ElementType.FIELD})
+public @interface ThreadRestricted {
+
+ /**
+ * @return A description of the thread or set of threads that this annotation describes a method or field
+ * being restricted to.
+ */
+ String value();
+
+ /**
+ * @return What type of access this annotation describes, when it is applied to a field.
+ * <br>
+ * This annotation describes all types of access ({@link Access#READ_WRITE}) by default.
+ */
+ Access fieldAccess() default Access.READ_WRITE;
+
+}