diff options
author | Yifan Hong <elsk@google.com> | 2017-02-22 18:28:23 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2017-02-22 18:28:24 +0000 |
commit | 057e74631b8b1c658ec9b67684bf486e1ec3e7e5 (patch) | |
tree | 73b4a3411b300e0d176d3440673c811efb61cd75 | |
parent | 52a60e08fb3c636b073a9b6a27672bbd3061e5b8 (diff) | |
parent | a57dffb151145529e71b22a8d7f985bc1de105f4 (diff) | |
download | native-057e74631b8b1c658ec9b67684bf486e1ec3e7e5.tar.gz |
Merge "lshal: Fix timeout causes unexpected exits."
-rw-r--r-- | cmds/lshal/Lshal.cpp | 8 | ||||
-rw-r--r-- | cmds/lshal/Timeout.h | 32 |
2 files changed, 32 insertions, 8 deletions
diff --git a/cmds/lshal/Lshal.cpp b/cmds/lshal/Lshal.cpp index ce058c8a47..6fd9b21368 100644 --- a/cmds/lshal/Lshal.cpp +++ b/cmds/lshal/Lshal.cpp @@ -469,9 +469,17 @@ int Lshal::main(int argc, char **argv) { return status; } +void signalHandler(int sig) { + if (sig == SIGINT) { + int retVal; + pthread_exit(&retVal); + } +} + } // namespace lshal } // namespace android int main(int argc, char **argv) { + signal(SIGINT, ::android::lshal::signalHandler); return ::android::lshal::Lshal{}.main(argc, argv); } diff --git a/cmds/lshal/Timeout.h b/cmds/lshal/Timeout.h index 001c3d6790..ca477bf615 100644 --- a/cmds/lshal/Timeout.h +++ b/cmds/lshal/Timeout.h @@ -29,7 +29,8 @@ static constexpr std::chrono::milliseconds IPC_CALL_WAIT{500}; class BackgroundTaskState { public: - BackgroundTaskState(){} + BackgroundTaskState(std::function<void(void)> &&func) + : mFunc(std::forward<decltype(func)>(func)) {} void notify() { std::unique_lock<std::mutex> lock(mMutex); mFinished = true; @@ -42,22 +43,37 @@ public: mCondVar.wait_until(lock, end, [this](){ return this->mFinished; }); return mFinished; } + void operator()() { + mFunc(); + } private: std::mutex mMutex; std::condition_variable mCondVar; bool mFinished = false; + std::function<void(void)> mFunc; }; +void *callAndNotify(void *data) { + BackgroundTaskState &state = *static_cast<BackgroundTaskState *>(data); + state(); + state.notify(); + return NULL; +} + template<class R, class P> -bool timeout(std::chrono::duration<R, P> delay, const std::function<void(void)> &func) { +bool timeout(std::chrono::duration<R, P> delay, std::function<void(void)> &&func) { auto now = std::chrono::system_clock::now(); - BackgroundTaskState state{}; - std::thread t([&state, &func] { - func(); - state.notify(); - }); - t.detach(); + BackgroundTaskState state{std::forward<decltype(func)>(func)}; + pthread_t thread; + if (pthread_create(&thread, NULL, callAndNotify, &state)) { + std::cerr << "FATAL: could not create background thread." << std::endl; + return false; + } bool success = state.wait(now + delay); + if (!success) { + pthread_kill(thread, SIGINT); + } + pthread_join(thread, NULL); return success; } |