blob: f0849707f96d7831077eff8ed2b21716c6f043b6 [file] [log] [blame]
Avichal Rakeshe1857f82022-06-08 17:47:23 -07001/*
2 * Copyright (C) 2022 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 "SimpleThread.h"
18
19namespace android {
20namespace hardware {
21namespace camera {
22namespace common {
23namespace helper {
24
25SimpleThread::SimpleThread() : mDone(true), mThread() {}
26SimpleThread::~SimpleThread() {
Shuzhen Wang465f11d2025-03-10 21:47:33 -070027 // b/399939768: We need to be careful calling requestExitAndWait() from
28 // the destructor due to the possibility of
29 // OutputThread::threadLoop->~ExternalCameraDeviceSession->~OutputThread::requestExit()
30 // resulting in join() called on the calling thread.
31 //
32 // Rather than removing `requestExitAndExit`, we guard the `join` call
33 // in it by checking the thread id.
Avichal Rakeshe1857f82022-06-08 17:47:23 -070034 requestExitAndWait();
35}
36
37void SimpleThread::run() {
38 requestExitAndWait(); // Exit current execution, if any.
39
40 // start thread
41 mDone.store(false, std::memory_order_release);
42 mThread = std::thread(&SimpleThread::runLoop, this);
43}
44
45void SimpleThread::requestExitAndWait() {
46 // Signal thread to stop
47 mDone.store(true, std::memory_order_release);
48
49 // Wait for thread to exit if needed. This should happen in no more than one iteration of
Shuzhen Wang465f11d2025-03-10 21:47:33 -070050 // threadLoop. Only call 'join' if this function is called from a thread
51 // different from the thread associated with this object. Otherwise call
52 // 'detach' so that the threadLoop can finish and clean up itself.
Avichal Rakeshe1857f82022-06-08 17:47:23 -070053 if (mThread.joinable()) {
Shuzhen Wang465f11d2025-03-10 21:47:33 -070054 if (mThread.get_id() != std::this_thread::get_id()) {
55 mThread.join();
56 } else {
57 mThread.detach();
58 }
Avichal Rakeshe1857f82022-06-08 17:47:23 -070059 }
60 mThread = std::thread();
61}
62
63void SimpleThread::runLoop() {
64 while (!exitPending()) {
65 if (!threadLoop()) {
66 break;
67 }
68 }
69}
70
71} // namespace helper
72} // namespace common
73} // namespace camera
74} // namespace hardware
75} // namespace android