1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "TraceProviderFuchsia.h"
18 
19 #include <log/log.h>
20 
21 #include <lib/async/cpp/task.h>
22 #include <lib/zx/channel.h>
23 
24 #include "services/service_connector.h"
25 
~TraceProviderFuchsia()26 TraceProviderFuchsia::~TraceProviderFuchsia() {
27     if (mTraceProvider) {
28         async::PostTask(mLoop.dispatcher(), [this]() {
29             // trace_provider_.reset() needs to run on loop_'s dispatcher or
30             // else its teardown can be racy and crash.
31             mTraceProvider.reset();
32             // Run Quit() in the loop to ensure this task executes before
33             // JoinThreads() returns and the destructor finishes.
34             mLoop.Quit();
35         });
36     } else {
37         mLoop.Quit();
38     }
39     mLoop.JoinThreads();
40 }
41 
TraceProviderFuchsia()42 TraceProviderFuchsia::TraceProviderFuchsia()
43     : mLoop(&kAsyncLoopConfigNeverAttachToThread) {}
44 
Initialize()45 bool TraceProviderFuchsia::Initialize() {
46     // Connect to fuchsia.tracing.provider.Registry service.
47     zx_handle_t client_channel =
48         GetConnectToServiceFunction()("/svc/fuchsia.tracing.provider.Registry");
49     if (client_channel == ZX_HANDLE_INVALID) {
50         ALOGE("Failed to connect to tracing provider service");
51         return false;
52     }
53 
54     zx_status_t status = mLoop.StartThread();
55     if (status != ZX_OK) {
56         ALOGE("Failed to start async loop: %d", status);
57         return false;
58     }
59 
60     mTraceProvider = std::make_unique<trace::TraceProvider>(
61         zx::channel(client_channel), mLoop.dispatcher());
62     return true;
63 }
64