blob: 86ea7e2c86d8b83caff4aa5e229f82eb6f0d7dc2 [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef LIB_FDIO_GET_CLIENT_H_
#define LIB_FDIO_GET_CLIENT_H_
#include <lib/fdio/directory.h>
#include <lib/fidl/cpp/wire/channel.h>
#include <lib/zx/result.h>
#include <fbl/no_destructor.h>
template <class T>
zx::result<typename fidl::WireSyncClient<T>>& get_client() {
// We can't destroy |client| at static destruction time as some multithreaded programs call exit()
// from one thread while other threads are calling in to fdio functions either directly or
// indirectly through libc. Destroying |client| in this scenario would result in crashes on those
// threads. See https://fxbug.dev/42069066 for details.
static fbl::NoDestructor<zx::result<typename fidl::WireSyncClient<T>>> client =
fbl::NoDestructor([]() -> zx::result<typename fidl::WireSyncClient<T>> {
auto endpoints = fidl::CreateEndpoints<T>();
if (endpoints.is_error()) {
return endpoints.take_error();
}
zx_status_t status = fdio_service_connect_by_name(fidl::DiscoverableProtocolName<T>,
endpoints->server.channel().release());
if (status != ZX_OK) {
return zx::error(status);
}
return zx::ok(fidl::WireSyncClient(std::move(endpoints->client)));
}());
return *client;
}
#endif // LIB_FDIO_GET_CLIENT_H_