org.pkl.thirdparty.truffle.api.ThreadLocalAction Maven / Gradle / Ivy
Show all versions of pkl-config-java-all Show documentation
/*
* Copyright (c) 2021, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
*
* Subject to the condition set forth below, permission is hereby granted to any
* person obtaining a copy of this software, associated documentation and/or
* data (collectively the "Software"), free of charge and under any and all
* copyright rights in the Software, and any and all patent rights owned or
* freely licensable by each licensor hereunder covering either (i) the
* unmodified Software as contributed to or provided by such licensor, or (ii)
* the Larger Works (as defined below), to deal in both
*
* (a) the Software, and
*
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
* one is included with the Software each a "Larger Work" to which the Software
* is contributed by such licensors),
*
* without restriction, including without limitation the rights to copy, create
* derivative works of, display, perform, and distribute the Software and make,
* use, sell, offer for sale, import, export, have made, and have sold the
* Software and the Larger Work(s), and to sublicense the foregoing rights on
* either these or other terms.
*
* This license is subject to the following condition:
*
* The above copyright notice and either this complete permission notice or at a
* minimum a reference to the UPL must be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.pkl.thirdparty.truffle.api;
import java.util.concurrent.Future;
import org.pkl.thirdparty.graalvm.polyglot.impl.AbstractPolyglotImpl;
import org.pkl.thirdparty.truffle.api.nodes.Node;
/**
* Represents an action that is executed at a {@link TruffleSafepoint safepoint} location of the
* guest language execution. Thread local actions can be submitted by
* {@link TruffleLanguage.Env#submitThreadLocal(Thread[], ThreadLocalAction) languages} or
* {@link org.pkl.thirdparty.truffle.api.instrumentation.TruffleInstrument.Env#submitThreadLocal(TruffleContext, Thread[], ThreadLocalAction)
* instruments}. When an action is submitted it will be {@link #perform(Access) performed} locally
* on the threads they are submitted to. After submitting a thread local action a {@link Future} is
* returned that allows to wait for and cancel the submitted action.
*
* Thread local actions can be configured to allow side-effects using the constructor of the action.
* If side-effects are allowed (true
), then the thread-local action is allowed to throw
* non-internal guest language exceptions from the action and modify the observable guest
* application state. Otherwise, the action is not allowed to modify the observable state, and any
* non-internal guest language exception will be transformed to an internal error of type
* {@link AssertionError}. Side-effects may be temporarily
* {@link TruffleSafepoint#setAllowSideEffects(boolean) disabled} by the guest language.
*
* Thread local actions can also be set to be executed in a synchronous or asynchronous way. A
* submitted synchronous thread-local action waits until it is started on all threads that it was
* submitted on. Then the action is {@link ThreadLocalAction#perform(Access) performed} on all
* threads. After they were performed on a thread, the action waits for all threads to complete. No
* synchronous thread-local actions can be submitted while performing synchronous actions, as this
* may lead to deadlocks. If a synchronous event is submitted during a synchronous event, then a
* {@link IllegalStateException} is thrown when the action is submitted. Asynchronous thread-local
* actions might start and complete to perform independently of each other. There is no restriction
* on how they may be submitted.
*
* Thread local actions are guaranteed to be executed in the same order as they were submitted for a
* context. If a context has pending thread-local actions, the actions may be canceled when the
* context is canceled or closed invalid. Exceptions thrown by the action will be forwarded handled
* by the guest language implementation. The only exception is for truffle exceptions that are
* thrown for non-side-effecting events.
*
* Example Usage:
*
*
* Env env; // language or instrument environment
*
* env.submitThreadLocal(null, new ThreadLocalAction(true, true) {
* @Override
* protected void perform(Access access) {
* assert access.getThread() == Thread.currentThread();
* }
*
* @Override
* protected String name() {
* return "MyAction"
* }
*
* });
*
*
*
*
* Further information can be found in the
* safepoint
* tutorial.
*
* @see TruffleSafepoint
* @see TruffleLanguage.Env#submitThreadLocal
* @see org.pkl.thirdparty.truffle.api.instrumentation.TruffleInstrument.Env#submitThreadLocal
* @since 21.1
*/
public abstract class ThreadLocalAction {
private final boolean hasSideEffects;
private final boolean synchronous;
private final boolean recurring;
/**
* Creates a new thread local action.
*
* @param hasSideEffects true if the event may have side-effects else false.
* @param synchronous true if the event should run synchronous else the event will run
* asynchronous.
* @see ThreadLocalAction
* @since 21.1
*/
protected ThreadLocalAction(boolean hasSideEffects, boolean synchronous) {
this(hasSideEffects, synchronous, false);
}
/**
* Creates a new thread local action.
*
* @param hasSideEffects true if the event may have side-effects else false.
* @param synchronous true if the event should run synchronous else the event will run
* asynchronous.
* @param recurring true if the event should be rescheduled until cancelled, else false.
* @see ThreadLocalAction
* @since 21.1
*/
protected ThreadLocalAction(boolean hasSideEffects, boolean synchronous, boolean recurring) {
this.hasSideEffects = hasSideEffects;
this.synchronous = synchronous;
this.recurring = recurring;
}
final boolean isSynchronous() {
return synchronous;
}
final boolean hasSideEffects() {
return hasSideEffects;
}
final boolean isRecurring() {
return recurring;
}
/**
* Performs the thread local action on a given thread.
*
* @param access allows access to the current thread, the code location and whether a context
* was active while executing the event.
* @see ThreadLocalAction
* @since 21.1
*/
protected abstract void perform(Access access);
/**
* Argument class for {@link ThreadLocalAction#perform(Access)}.
*
* @since 21.1
*/
public abstract static class Access {
/**
* Constructor for framework use only.
*
* @since 21.1
*/
protected Access(AbstractPolyglotImpl impl) {
if (impl == null) {
throw new AssertionError("Constructor for framework use only.");
}
}
/**
* Returns the current node location executing on this thread. The return value is
* guaranteed to be non-null.
*
* @since 21.1
*/
public abstract Node getLocation();
/**
* Returns the thread where this thread local action is running on. Currently this always
* returns {@link Thread#currentThread()}. See the
* safepoint
* tutorial for further details on our plans.
*
* @since 21.1
*/
public abstract Thread getThread();
}
}