#include "src/objects/js-atomics-synchronization.h"
#include "src/base/macros.h"
#include "src/base/platform/yield-processor.h"
#include "src/execution/isolate-inl.h"
#include "src/objects/js-atomics-synchronization-inl.h"
#include "src/objects/js-promise-inl.h"
#include "src/objects/waiter-queue-node.h"
#include "src/sandbox/external-pointer-inl.h"
namespace v8 {
namespace internal {
namespace detail {
class WaiterQueueNode;
}
namespace {
MaybeHandle<JSReceiver> PerformPromiseThen(
Isolate* isolate, Handle<JSReceiver> promise,
Handle<Object> fulfill_handler,
MaybeHandle<JSFunction> maybe_reject_handler = MaybeHandle<JSFunction>()) { … }
MaybeHandle<Context> SetAsyncUnlockHandlers(
Isolate* isolate, DirectHandle<JSAtomicsMutex> mutex,
Handle<JSReceiver> waiting_for_callback_promise,
DirectHandle<JSPromise> unlocked_promise) { … }
void AddPromiseToNativeContext(Isolate* isolate,
DirectHandle<JSPromise> promise) { … }
void RemovePromiseFromNativeContext(Isolate* isolate,
DirectHandle<JSPromise> promise) { … }
template <typename T>
Global<T> GetWeakGlobal(Isolate* isolate, Local<T> object) { … }
}
namespace detail {
class V8_NODISCARD WaiterQueueLockGuard final { … };
class V8_NODISCARD SyncWaiterQueueNode final : public WaiterQueueNode { … };
template <typename T>
class AsyncWaiterNotifyTask : public CancelableTask { … };
template <typename T>
class AsyncWaiterTimeoutTask : public CancelableTask { … };
template <typename T>
class V8_NODISCARD AsyncWaiterQueueNode final : public WaiterQueueNode { … };
}
SyncWaiterQueueNode;
LockAsyncWaiterQueueNode;
WaitAsyncWaiterQueueNode;
AsyncWaitTimeoutTask;
AsyncLockTimeoutTask;
void JSSynchronizationPrimitive::IsolateDeinit(Isolate* isolate) { … }
void JSSynchronizationPrimitive::CleanupAsyncWaiterLists(
Isolate* isolate, DequeueMatcher matcher) { … }
bool JSSynchronizationPrimitive::TryLockWaiterQueueExplicit(
std::atomic<StateT>* state, StateT& expected) { … }
void JSSynchronizationPrimitive::SetWaiterQueueStateOnly(
std::atomic<StateT>* state, StateT new_state) { … }
Tagged<Object> JSSynchronizationPrimitive::NumWaitersForTesting(
Isolate* requester) { … }
Handle<JSObject> JSAtomicsMutex::CreateResultObject(Isolate* isolate,
DirectHandle<Object> value,
bool success) { … }
void JSAtomicsMutex::CleanupMatchingAsyncWaiters(Isolate* isolate,
WaiterQueueNode* node,
DequeueMatcher matcher) { … }
bool JSAtomicsMutex::TryLockExplicit(std::atomic<StateT>* state,
StateT& expected) { … }
bool JSAtomicsMutex::BackoffTryLock(Isolate* requester,
DirectHandle<JSAtomicsMutex> mutex,
std::atomic<StateT>* state) { … }
bool JSAtomicsMutex::MaybeEnqueueNode(Isolate* requester,
DirectHandle<JSAtomicsMutex> mutex,
std::atomic<StateT>* state,
WaiterQueueNode* this_waiter) { … }
std::optional<WaiterQueueLockGuard> JSAtomicsMutex::LockWaiterQueueOrJSMutex(
std::atomic<StateT>* state, StateT& current_state) { … }
bool JSAtomicsMutex::LockJSMutexOrDequeueTimedOutWaiter(
Isolate* requester, std::atomic<StateT>* state,
WaiterQueueNode* timed_out_waiter) { … }
bool JSAtomicsMutex::LockSlowPath(Isolate* requester,
DirectHandle<JSAtomicsMutex> mutex,
std::atomic<StateT>* state,
std::optional<base::TimeDelta> timeout) { … }
void JSAtomicsMutex::UnlockSlowPath(Isolate* requester,
std::atomic<StateT>* state) { … }
MaybeHandle<JSPromise> JSAtomicsMutex::LockOrEnqueuePromise(
Isolate* requester, Handle<JSAtomicsMutex> mutex, Handle<Object> callback,
std::optional<base::TimeDelta> timeout) { … }
bool JSAtomicsMutex::LockAsync(Isolate* requester, Handle<JSAtomicsMutex> mutex,
Handle<JSPromise> internal_locked_promise,
MaybeHandle<JSPromise> unlocked_promise,
LockAsyncWaiterQueueNode** waiter_node,
std::optional<base::TimeDelta> timeout) { … }
Handle<JSPromise> JSAtomicsMutex::LockAsyncWrapperForWait(
Isolate* requester, Handle<JSAtomicsMutex> mutex) { … }
bool JSAtomicsMutex::LockAsyncSlowPath(
Isolate* isolate, Handle<JSAtomicsMutex> mutex, std::atomic<StateT>* state,
Handle<JSPromise> internal_locked_promise,
MaybeHandle<JSPromise> unlocked_promise,
LockAsyncWaiterQueueNode** waiter_node,
std::optional<base::TimeDelta> timeout) { … }
bool JSAtomicsMutex::LockOrEnqueueAsyncNode(Isolate* isolate,
DirectHandle<JSAtomicsMutex> mutex,
LockAsyncWaiterQueueNode* waiter) { … }
void JSAtomicsMutex::UnlockAsyncLockedMutex(
Isolate* requester, DirectHandle<Foreign> async_locked_waiter_wrapper) { … }
bool JSAtomicsMutex::DequeueTimedOutAsyncWaiter(
Isolate* requester, DirectHandle<JSAtomicsMutex> mutex,
std::atomic<StateT>* state, WaiterQueueNode* timed_out_waiter) { … }
void JSAtomicsMutex::HandleAsyncTimeout(LockAsyncWaiterQueueNode* waiter) { … }
void JSAtomicsMutex::HandleAsyncNotify(LockAsyncWaiterQueueNode* waiter) { … }
void JSAtomicsCondition::CleanupMatchingAsyncWaiters(Isolate* isolate,
WaiterQueueNode* node,
DequeueMatcher matcher) { … }
void JSAtomicsCondition::QueueWaiter(Isolate* requester,
DirectHandle<JSAtomicsCondition> cv,
WaiterQueueNode* waiter) { … }
bool JSAtomicsCondition::WaitFor(Isolate* requester,
DirectHandle<JSAtomicsCondition> cv,
Handle<JSAtomicsMutex> mutex,
std::optional<base::TimeDelta> timeout) { … }
uint32_t JSAtomicsCondition::DequeueExplicit(
Isolate* requester, DirectHandle<JSAtomicsCondition> cv,
std::atomic<StateT>* state, const DequeueAction& action_under_lock) { … }
uint32_t JSAtomicsCondition::Notify(Isolate* requester,
DirectHandle<JSAtomicsCondition> cv,
uint32_t count) { … }
MaybeHandle<JSReceiver> JSAtomicsCondition::WaitAsync(
Isolate* requester, Handle<JSAtomicsCondition> cv,
DirectHandle<JSAtomicsMutex> mutex,
std::optional<base::TimeDelta> timeout) { … }
void JSAtomicsCondition::HandleAsyncTimeout(WaitAsyncWaiterQueueNode* waiter) { … }
void JSAtomicsCondition::HandleAsyncNotify(WaitAsyncWaiterQueueNode* waiter) { … }
}
}