#include <unistd.h>
#include <filesystem>
+#include <fstream>
#include <string>
#include <vector>
return tasks;
}
+std::string GetThreadName(pid_t tid) {
+ std::string path = "/proc/" + std::to_string(tid) + "/comm";
+ std::ifstream proc_file(path);
+ if (proc_file.is_open()) {
+ std::string name;
+ std::getline(proc_file, name);
+ proc_file.close();
+ return name;
+ }
+
+ _E("Failed to read name. tid(%d)", tid);
+ return "";
+}
+
+int GetThreadCountWithoutGmain(const std::vector<pid_t>& tasks) {
+ int count = tasks.size() - 1;
+ for (auto tid : tasks) {
+ if (getpid() != tid) {
+ // Unfortunately, the signal handler of the gmain thread is not invoked.
+ // The gmain thread always calls poll().
+ // To avoid delay issue of calling usleep(), this function decreases
+ // the count if the gmain threads exists.
+ if (GetThreadName(tid) == "gmain") {
+ _D("%d is gmain thread", tid);
+ count--;
+ }
+ }
+ }
+
+ return count;
+}
+
} // namespace
ThreadControl& ThreadControl::GetInst() {
void ThreadControl::InterruptThreads() {
pid_t pid = getpid();
auto tasks = GetTasks();
- count_ = tasks.size() - 1;
+ count_ = GetThreadCountWithoutGmain(tasks);
_D("tasks count: %d", count_);
for (auto& tid : tasks) {
if (tid != pid) {
void ThreadControl::ContinueThreads() {
std::unique_lock<std::mutex> lock(mutex_);
- count_ = GetTasks().size() - 1;
+ count_ = GetThreadCountWithoutGmain(GetTasks());
_D("tasks count: %d", count_);
done_ = true;
cond_.notify_all();
}
void ThreadControl::SignalHandler(int signo) {
- _W("Block");
+ _D("Block");
auto& inst = ThreadControl::GetInst();
std::unique_lock<std::mutex> lock(inst.mutex_);
inst.count_--;
- inst.cond_.wait(lock, [&] { return inst.done_; });
+ if (inst.cond_.wait_for(lock, std::chrono::seconds(5),
+ [&] { return inst.done_; }))
+ _D("Unblock");
+ else
+ _E("Timed out");
inst.count_--;
- _W("Unblock");
}
} // namespace launchpad