mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-12-01 01:36:09 +03:00
102 lines
3.2 KiB
C++
102 lines
3.2 KiB
C++
|
// Copyright 2018 The Chromium Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style license that can be
|
||
|
// found in the LICENSE file.
|
||
|
|
||
|
#include "base/fuchsia/service_directory.h"
|
||
|
|
||
|
#include <lib/async/default.h>
|
||
|
#include <lib/svc/dir.h>
|
||
|
#include <lib/zx/channel.h>
|
||
|
#include <zircon/process.h>
|
||
|
#include <zircon/processargs.h>
|
||
|
|
||
|
#include "base/fuchsia/fuchsia_logging.h"
|
||
|
#include "base/message_loop/message_loop_current.h"
|
||
|
#include "base/no_destructor.h"
|
||
|
|
||
|
namespace base {
|
||
|
namespace fuchsia {
|
||
|
|
||
|
ServiceDirectory::ServiceDirectory(zx::channel directory_request) {
|
||
|
zx_status_t status = svc_dir_create(async_get_default_dispatcher(),
|
||
|
directory_request.release(), &svc_dir_);
|
||
|
ZX_CHECK(status == ZX_OK, status);
|
||
|
}
|
||
|
|
||
|
ServiceDirectory::~ServiceDirectory() {
|
||
|
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||
|
DCHECK(services_.empty());
|
||
|
|
||
|
zx_status_t status = svc_dir_destroy(svc_dir_);
|
||
|
ZX_DCHECK(status == ZX_OK, status);
|
||
|
}
|
||
|
|
||
|
// static
|
||
|
ServiceDirectory* ServiceDirectory::GetDefault() {
|
||
|
static base::NoDestructor<ServiceDirectory> directory(
|
||
|
zx::channel(zx_take_startup_handle(PA_DIRECTORY_REQUEST)));
|
||
|
return directory.get();
|
||
|
}
|
||
|
|
||
|
void ServiceDirectory::AddService(StringPiece name,
|
||
|
ConnectServiceCallback connect_callback) {
|
||
|
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||
|
DCHECK(services_.find(name) == services_.end());
|
||
|
|
||
|
std::string name_str = name.as_string();
|
||
|
services_[name_str] = connect_callback;
|
||
|
|
||
|
zx_status_t status =
|
||
|
svc_dir_add_service(svc_dir_, "public", name_str.c_str(), this,
|
||
|
&ServiceDirectory::HandleConnectRequest);
|
||
|
ZX_DCHECK(status == ZX_OK, status);
|
||
|
|
||
|
// Publish to the legacy "flat" namespace, which is required by some clients.
|
||
|
status = svc_dir_add_service(svc_dir_, nullptr, name_str.c_str(), this,
|
||
|
&ServiceDirectory::HandleConnectRequest);
|
||
|
ZX_DCHECK(status == ZX_OK, status);
|
||
|
}
|
||
|
|
||
|
void ServiceDirectory::RemoveService(StringPiece name) {
|
||
|
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||
|
|
||
|
std::string name_str = name.as_string();
|
||
|
|
||
|
auto it = services_.find(name_str);
|
||
|
DCHECK(it != services_.end());
|
||
|
services_.erase(it);
|
||
|
|
||
|
zx_status_t status =
|
||
|
svc_dir_remove_service(svc_dir_, "public", name_str.c_str());
|
||
|
ZX_DCHECK(status == ZX_OK, status);
|
||
|
|
||
|
// Unregister from the legacy "flat" namespace.
|
||
|
status = svc_dir_remove_service(svc_dir_, nullptr, name_str.c_str());
|
||
|
ZX_DCHECK(status == ZX_OK, status);
|
||
|
}
|
||
|
|
||
|
void ServiceDirectory::RemoveAllServices() {
|
||
|
while (!services_.empty()) {
|
||
|
RemoveService(services_.begin()->first);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// static
|
||
|
void ServiceDirectory::HandleConnectRequest(void* context,
|
||
|
const char* service_name,
|
||
|
zx_handle_t service_request) {
|
||
|
auto* directory = reinterpret_cast<ServiceDirectory*>(context);
|
||
|
DCHECK_CALLED_ON_VALID_THREAD(directory->thread_checker_);
|
||
|
|
||
|
auto it = directory->services_.find(service_name);
|
||
|
|
||
|
// HandleConnectRequest() is expected to be called only for registered
|
||
|
// services.
|
||
|
DCHECK(it != directory->services_.end());
|
||
|
|
||
|
it->second.Run(zx::channel(service_request));
|
||
|
}
|
||
|
|
||
|
} // namespace fuchsia
|
||
|
} // namespace base
|