Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/jsc/AbortSignal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ impl AbortSignal {
WebCore__AbortSignal__decrementPendingActivity(self)
}

/// This function is not threadsafe. aborted is a boolean, not an atomic!
/// Readable from any thread (an atomic load); whoever calls it keeps the signal alive.
pub fn aborted(&self) -> bool {
WebCore__AbortSignal__aborted(self)
}
Expand Down
45 changes: 17 additions & 28 deletions src/jsc/bindings/webcore/AbortSignal.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ class AbortSignal final : public RefCounted<AbortSignal>, public EventTargetWith
void signalAbort(JSC::JSGlobalObject* globalObject, CommonAbortReason reason);
void signalAbort(JSC::JSValue reason);

bool aborted() const { return m_flags & static_cast<uint8_t>(AbortSignalFlags::Aborted); }
// Readable from any thread (thread-pool work polls it); the caller keeps the signal alive.
bool aborted() const { return flags() & static_cast<uint8_t>(AbortSignalFlags::Aborted); }
void markAborted(JSC::JSValue reason);
void runAbortSteps();

Expand All @@ -102,8 +103,8 @@ class AbortSignal final : public RefCounted<AbortSignal>, public EventTargetWith
}

bool hasActiveTimeoutTimer() const { return m_timeout != nullptr; }
bool hasAbortEventListener() const { return m_flags & static_cast<uint8_t>(AbortSignalFlags::HasAbortEventListener); }
bool isFiringEventListeners() const { return m_flags & static_cast<uint8_t>(AbortSignalFlags::IsFiringEventListeners); }
bool hasAbortEventListener() const { return flags() & static_cast<uint8_t>(AbortSignalFlags::HasAbortEventListener); }
bool isFiringEventListeners() const { return flags() & static_cast<uint8_t>(AbortSignalFlags::IsFiringEventListeners); }

// ContextDestructionObserver.
void ref() const final { RefCounted::ref(); }
Expand Down Expand Up @@ -147,7 +148,7 @@ class AbortSignal final : public RefCounted<AbortSignal>, public EventTargetWith
m_timeoutObserverCount.fetch_sub(1, std::memory_order_relaxed);
}
bool hasPendingActivity() const { return pendingActivityCount > 0; }
bool isDependent() const { return m_flags & static_cast<uint8_t>(AbortSignalFlags::Dependent); }
bool isDependent() const { return flags() & static_cast<uint8_t>(AbortSignalFlags::Dependent); }

size_t memoryCost() const;

Expand All @@ -166,31 +167,19 @@ class AbortSignal final : public RefCounted<AbortSignal>, public EventTargetWith
void releaseSourceObserverCounts();
void cancelTimer();

void applyFlags(uint8_t flags) { m_flags |= flags; }
void setIsDependent(bool isDependent)
// Written on the owning thread only; also read by GC marker threads (JSAbortSignalOwner) and by thread-pool work (aborted()).
uint8_t flags() const { return m_flags.load(std::memory_order_relaxed); }
void applyFlags(uint8_t bits) { m_flags.fetch_or(bits, std::memory_order_relaxed); }
void setFlag(AbortSignalFlags flag, bool on)
{
if (isDependent) {
m_flags |= static_cast<uint8_t>(AbortSignalFlags::Dependent);
} else {
m_flags &= ~static_cast<uint8_t>(AbortSignalFlags::Dependent);
}
}
void setHasAbortEventListener(bool hasAbortEventListener)
{
if (hasAbortEventListener) {
m_flags |= static_cast<uint8_t>(AbortSignalFlags::HasAbortEventListener);
} else {
m_flags &= ~static_cast<uint8_t>(AbortSignalFlags::HasAbortEventListener);
}
}
void setIsFiringEventListeners(bool isFiringEventListeners)
{
if (isFiringEventListeners) {
m_flags |= static_cast<uint8_t>(AbortSignalFlags::IsFiringEventListeners);
} else {
m_flags &= ~static_cast<uint8_t>(AbortSignalFlags::IsFiringEventListeners);
}
if (on)
m_flags.fetch_or(static_cast<uint8_t>(flag), std::memory_order_relaxed);
else
m_flags.fetch_and(static_cast<uint8_t>(~static_cast<uint8_t>(flag)), std::memory_order_relaxed);
}
void setIsDependent(bool isDependent) { setFlag(AbortSignalFlags::Dependent, isDependent); }
void setHasAbortEventListener(bool hasAbortEventListener) { setFlag(AbortSignalFlags::HasAbortEventListener, hasAbortEventListener); }
void setIsFiringEventListeners(bool isFiringEventListeners) { setFlag(AbortSignalFlags::IsFiringEventListeners, isFiringEventListeners); }

// EventTarget.
EventTargetInterface eventTargetInterface() const final { return AbortSignalEventTargetInterfaceType; }
Expand Down Expand Up @@ -219,7 +208,7 @@ class AbortSignal final : public RefCounted<AbortSignal>, public EventTargetWith
std::atomic<uint32_t> m_timeoutObserverCount { 0 };
uint32_t m_algorithmIdentifier { 0 };
AbortSignalTimeout m_timeout { nullptr };
uint8_t m_flags { 0 };
std::atomic<uint8_t> m_flags { 0 };
};

WebCoreOpaqueRoot root(AbortSignal*);
Expand Down
Loading