Commit 4794b98c authored by Lee Howes's avatar Lee Howes Committed by Facebook GitHub Bot

Add a termination tag to the blocking context

Summary:
Add a termination tag that carries through the blocking context chain. This flag notifies logging operations that they may go as far as to terminate the process if blocking operations are detected.

The flags carry through the blocking scopes so the termination flag will stay present while we enable and disable blocking - it would be sticky for a given thread once set.

Reviewed By: yfeldblum

Differential Revision: D27869075

fbshipit-source-id: 27014a3e6c9b28c0f433949a576bb6116e7c06c0
parent da606bda
......@@ -51,35 +51,56 @@ void Executor::keepAliveRelease() noexcept {
<< "which do not override keepAliveAcquire()";
}
// Base case of permitting with no termination to avoid nullptr tests
static ExecutorBlockingList emptyList{nullptr, {false, false, {}}};
#if defined(FOLLY_TLS)
extern constexpr bool const executor_blocking_list_enabled = true;
thread_local ExecutorBlockingList* executor_blocking_list = nullptr;
thread_local ExecutorBlockingList* executor_blocking_list = &emptyList;
#else
extern constexpr bool const executor_blocking_list_enabled = false;
ExecutorBlockingList* executor_blocking_list = nullptr;
ExecutorBlockingList* executor_blocking_list = &emptyList;
#endif
Optional<ExecutorBlockingContext> getExecutorBlockingContext() noexcept {
return //
!executor_blocking_list || !executor_blocking_list->forbid ? none : //
!executor_blocking_list->curr.forbid ? none : //
make_optional(executor_blocking_list->curr);
}
ExecutorBlockingGuard::ExecutorBlockingGuard(PermitTag) noexcept
: list_{false, executor_blocking_list, {}} {
: list_{*executor_blocking_list} {
if (executor_blocking_list_enabled) {
list_.prev = executor_blocking_list;
list_.curr.forbid = false;
list_.curr.name = {};
executor_blocking_list = &list_;
}
}
ExecutorBlockingGuard::ExecutorBlockingGuard(
TrackTag, StringPiece name) noexcept
: list_{true, executor_blocking_list, {name}} {
: list_{*executor_blocking_list} {
if (executor_blocking_list_enabled) {
list_.prev = executor_blocking_list;
list_.curr.forbid = true;
list_.curr.name = name;
executor_blocking_list = &list_;
}
}
ExecutorBlockingGuard::ExecutorBlockingGuard(
ProhibitTag, StringPiece name) noexcept
: list_{*executor_blocking_list} {
if (executor_blocking_list_enabled) {
list_.prev = executor_blocking_list;
list_.curr.forbid = true;
list_.curr.allowTerminationOnBlocking = true;
list_.curr.name = name;
executor_blocking_list = &list_;
}
}
......
......@@ -307,6 +307,8 @@ Executor::KeepAlive<ExecutorT> getKeepAliveToken(
}
struct ExecutorBlockingContext {
bool forbid;
bool allowTerminationOnBlocking;
StringPiece name;
};
static_assert(
......@@ -314,7 +316,6 @@ static_assert(
"non-standard layout");
struct ExecutorBlockingList {
bool forbid;
ExecutorBlockingList* prev;
ExecutorBlockingContext curr;
};
......@@ -326,12 +327,14 @@ class ExecutorBlockingGuard {
public:
struct PermitTag {};
struct TrackTag {};
struct ProhibitTag {};
~ExecutorBlockingGuard();
ExecutorBlockingGuard() = delete;
explicit ExecutorBlockingGuard(PermitTag) noexcept;
explicit ExecutorBlockingGuard(TrackTag, StringPiece name) noexcept;
explicit ExecutorBlockingGuard(ProhibitTag, StringPiece name) noexcept;
ExecutorBlockingGuard(ExecutorBlockingGuard&&) = delete;
ExecutorBlockingGuard(ExecutorBlockingGuard const&) = delete;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment