blob: bf1b5401f1963114f8b92f1825084fea7d5e25a5 [file] [log] [blame]
/*
*
* Copyright (c) 2021 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include "loader_service.h"
#include <fidl/fuchsia.io/cpp/wire.h>
#include <fidl/fuchsia.opencl.loader/cpp/wire.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/io.h>
#include <lib/fidl/llcpp/connect_service.h>
#include <lib/service/llcpp/service.h>
#include <lib/syslog/global.h>
#include <stdio.h>
#include <threads.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
static fidl::WireSyncClient<fuchsia_opencl_loader::Loader> opencl_loader_svc;
static zx_handle_t device_fs = ZX_HANDLE_INVALID;
constexpr const char* kTag = "opencl";
void connect_to_opencl_loader_svc() {
auto svc = service::OpenServiceRoot();
auto client_end = service::ConnectAt<fuchsia_opencl_loader::Loader>(*svc);
if (!client_end.is_ok()) {
FX_LOGF(ERROR, kTag, "connect_to_opencl_loader_svc: Failed to connect to loader service: %s",
client_end.status_string());
return;
}
auto client = fidl::BindSyncClient(std::move(*client_end));
auto feature_result = client->GetSupportedFeatures();
fuchsia_opencl_loader::wire::Features features;
if (!feature_result.ok()) {
FX_LOGF(
ERROR, kTag,
"connect_to_opencl_loader_svc: Failed to get supported features, error \"%s\". Retrying.",
feature_result.error().lossy_description());
// If GetSupportedFeatures isn't available the connection will be closed.
// If that happens, reconnect and assume a default set of features.
auto client_end = service::ConnectAt<fuchsia_opencl_loader::Loader>(*svc);
if (!client_end.is_ok()) {
FX_LOGF(ERROR, NULL,
"connect_to_opencl_loader_svc: Failed to reconnect to loader service: %s",
client_end.status_string());
return;
}
client = fidl::BindSyncClient(std::move(*client_end));
features = fuchsia_opencl_loader::wire::Features::kGet;
} else {
features = feature_result->features;
}
zx::channel device_fs_client;
if (features & fuchsia_opencl_loader::wire::Features::kConnectToDeviceFs) {
zx::channel device_fs_server;
zx_status_t status = zx::channel::create(0, &device_fs_server, &device_fs_client);
if (status != ZX_OK) {
FX_LOGF(ERROR, kTag, "connect_to_opencl_loader_svc: Failed to create channel: %s",
zx_status_get_string(status));
return;
}
auto result = client->ConnectToDeviceFs(std::move(device_fs_server));
if (!result.ok()) {
FX_LOGF(ERROR, kTag, "connect_to_opencl_loader_svc: Failed to connect to device fs: %s",
result.status_string());
return;
}
}
opencl_loader_svc = std::move(client);
device_fs = device_fs_client.release();
}
static once_flag svc_connect_once_flag = ONCE_FLAG_INIT;
fidl::WireSyncClient<fuchsia_opencl_loader::Loader>& get_opencl_loader_service() {
call_once(&svc_connect_once_flag, connect_to_opencl_loader_svc);
return opencl_loader_svc;
}
zx_handle_t get_device_fs() {
call_once(&svc_connect_once_flag, connect_to_opencl_loader_svc);
return device_fs;
}