Commit 37cdd9e6 authored by Wez's avatar Wez Committed by Commit Bot

[Fuchsia] Switch DCHECK to WARNING when service directory not connected.

Since it is possible for a parent process to exit without waiting for
its children to teardown, child processes may attempt to open /svc only
after it has been torn-down, causing no Directory handle to be returned.

ServiceDirectoryClient::ForCurrentProcess() now returns an instance not
connected to any actual directory, rather than crashing, if it is unable
to open "/svc".

Bug: 950672
Change-Id: I6f4acfa1c325d7831a3d5bf28cf04a8d1a3d66dd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1560376
Commit-Queue: Wez <wez@chromium.org>
Reviewed-by: default avatarSergey Ulanov <sergeyu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#650579}
parent b8741ce0
......@@ -10,23 +10,12 @@
#include "base/fuchsia/file_utils.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/no_destructor.h"
namespace base {
namespace fuchsia {
namespace {
// Singleton container for the process-global ServiceDirectoryClient instance.
std::unique_ptr<ServiceDirectoryClient>* ProcessServiceDirectoryClient() {
static base::NoDestructor<std::unique_ptr<ServiceDirectoryClient>>
service_directory_client_ptr(std::make_unique<ServiceDirectoryClient>(
OpenDirectory(base::FilePath(kServiceDirectoryPath))));
return service_directory_client_ptr.get();
}
} // namespace
ServiceDirectoryClient::ServiceDirectoryClient(
fidl::InterfaceHandle<::fuchsia::io::Directory> directory)
: directory_(std::move(directory)) {
......@@ -37,7 +26,7 @@ ServiceDirectoryClient::~ServiceDirectoryClient() = default;
// static
const ServiceDirectoryClient* ServiceDirectoryClient::ForCurrentProcess() {
return ProcessServiceDirectoryClient()->get();
return ServiceDirectoryClient::ProcessInstance()->get();
}
zx_status_t ServiceDirectoryClient::ConnectToServiceUnsafe(
......@@ -48,19 +37,40 @@ zx_status_t ServiceDirectoryClient::ConnectToServiceUnsafe(
request.release());
}
ServiceDirectoryClient::ServiceDirectoryClient() {}
// static
std::unique_ptr<ServiceDirectoryClient>
ServiceDirectoryClient::CreateForProcess() {
fidl::InterfaceHandle<::fuchsia::io::Directory> directory =
OpenDirectory(base::FilePath(kServiceDirectoryPath));
if (directory)
return std::make_unique<ServiceDirectoryClient>(std::move(directory));
LOG(WARNING) << "/svc is not available.";
return base::WrapUnique(new ServiceDirectoryClient);
}
// static
std::unique_ptr<ServiceDirectoryClient>*
ServiceDirectoryClient::ProcessInstance() {
static base::NoDestructor<std::unique_ptr<ServiceDirectoryClient>>
service_directory_client_ptr(CreateForProcess());
return service_directory_client_ptr.get();
}
ScopedServiceDirectoryClientForCurrentProcessForTest::
ScopedServiceDirectoryClientForCurrentProcessForTest(
fidl::InterfaceHandle<::fuchsia::io::Directory> directory)
: old_client_(std::move(*ProcessServiceDirectoryClient())) {
*ProcessServiceDirectoryClient() =
: old_client_(std::move(*ServiceDirectoryClient::ProcessInstance())) {
*ServiceDirectoryClient::ProcessInstance() =
std::make_unique<ServiceDirectoryClient>(std::move(directory));
client_ = ProcessServiceDirectoryClient()->get();
client_ = ServiceDirectoryClient::ProcessInstance()->get();
}
ScopedServiceDirectoryClientForCurrentProcessForTest::
~ScopedServiceDirectoryClientForCurrentProcessForTest() {
DCHECK_EQ(ProcessServiceDirectoryClient()->get(), client_);
*ProcessServiceDirectoryClient() = std::move(old_client_);
DCHECK_EQ(ServiceDirectoryClient::ProcessInstance()->get(), client_);
*ServiceDirectoryClient::ProcessInstance() = std::move(old_client_);
}
} // namespace fuchsia
......
......@@ -25,6 +25,8 @@ class SynchronousInterfacePtr;
namespace base {
namespace fuchsia {
class ScopedServiceDirectoryClientForCurrentProcessForTest;
// Helper for connecting to services from a supplied fuchsia.io.Directory.
class BASE_EXPORT ServiceDirectoryClient {
public:
......@@ -69,6 +71,18 @@ class BASE_EXPORT ServiceDirectoryClient {
zx::channel request) const;
private:
friend class ScopedServiceDirectoryClientForCurrentProcessForTest;
ServiceDirectoryClient();
// Creates a ServiceDirectoryClient connected to the process' "/svc"
// directory, or a dummy instance if the "/svc" directory is not available.
static std::unique_ptr<ServiceDirectoryClient> CreateForProcess();
// Returns the container holding the ForCurrentProcess() instance. The
// default ServiceDirectoryClient is created the first time this function is
// called.
static std::unique_ptr<ServiceDirectoryClient>* ProcessInstance();
const fidl::InterfaceHandle<::fuchsia::io::Directory> directory_;
DISALLOW_COPY_AND_ASSIGN(ServiceDirectoryClient);
......
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