mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Fix a race when terminating sandbox from another thread
PiperOrigin-RevId: 436695251 Change-Id: I50599cefb346813f594982641c78dc902e10ccb5
This commit is contained in:
parent
ab9c4afb15
commit
fb690062cf
|
@ -200,6 +200,7 @@ absl::Status Sandbox::Init() {
|
||||||
|
|
||||||
s2_ = absl::make_unique<sandbox2::Sandbox2>(std::move(executor),
|
s2_ = absl::make_unique<sandbox2::Sandbox2>(std::move(executor),
|
||||||
std::move(s2p), CreateNotifier());
|
std::move(s2p), CreateNotifier());
|
||||||
|
s2_awaited_ = false;
|
||||||
auto res = s2_->RunAsync();
|
auto res = s2_->RunAsync();
|
||||||
|
|
||||||
comms_ = s2_->comms();
|
comms_ = s2_->comms();
|
||||||
|
@ -432,9 +433,9 @@ absl::StatusOr<std::string> Sandbox::GetCString(const v::RemotePtr& str,
|
||||||
}
|
}
|
||||||
|
|
||||||
const sandbox2::Result& Sandbox::AwaitResult() {
|
const sandbox2::Result& Sandbox::AwaitResult() {
|
||||||
if (s2_) {
|
if (s2_ && !s2_awaited_) {
|
||||||
result_ = s2_->AwaitResult();
|
result_ = s2_->AwaitResult();
|
||||||
s2_.reset(nullptr);
|
s2_awaited_ = true;
|
||||||
}
|
}
|
||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,6 +149,10 @@ class Sandbox {
|
||||||
|
|
||||||
// The main sandbox2::Sandbox2 object.
|
// The main sandbox2::Sandbox2 object.
|
||||||
std::unique_ptr<sandbox2::Sandbox2> s2_;
|
std::unique_ptr<sandbox2::Sandbox2> s2_;
|
||||||
|
// Marks whether Sandbox2 result was already fetched.
|
||||||
|
// We cannot just delete s2_ as Terminate might be called from another thread
|
||||||
|
// and comms object can be still in use then.
|
||||||
|
bool s2_awaited_ = false;
|
||||||
|
|
||||||
// Result of the most recent sandbox execution
|
// Result of the most recent sandbox execution
|
||||||
sandbox2::Result result_;
|
sandbox2::Result result_;
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include <thread> // NOLINT(build/c++11)
|
||||||
|
|
||||||
#include "benchmark/benchmark.h"
|
#include "benchmark/benchmark.h"
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
@ -262,5 +264,20 @@ TEST(SandboxTest, NoRaceInAwaitResult) {
|
||||||
EXPECT_THAT(result.final_status(), Eq(sandbox2::Result::VIOLATION));
|
EXPECT_THAT(result.final_status(), Eq(sandbox2::Result::VIOLATION));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(SandboxTest, NoRaceInConcurrentTerminate) {
|
||||||
|
SumSandbox sandbox;
|
||||||
|
ASSERT_THAT(sandbox.Init(), IsOk());
|
||||||
|
SumApi api(&sandbox);
|
||||||
|
std::thread th([&sandbox] {
|
||||||
|
// Sleep so that the call already starts
|
||||||
|
absl::SleepFor(absl::Seconds(1));
|
||||||
|
sandbox.Terminate(/*attempt_graceful_exit=*/false);
|
||||||
|
});
|
||||||
|
EXPECT_THAT(api.sleep_for_sec(10), StatusIs(absl::StatusCode::kUnavailable));
|
||||||
|
th.join();
|
||||||
|
const auto& result = sandbox.AwaitResult();
|
||||||
|
EXPECT_THAT(result.final_status(), Eq(sandbox2::Result::EXTERNAL_KILL));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace sapi
|
} // namespace sapi
|
||||||
|
|
Loading…
Reference in New Issue
Block a user