| 43 | } |
| 44 | |
| 45 | int thread_base::_thread_run(thread_base* this_thread_obj) { |
| 46 | set_current_thread_name(this_thread_obj->thread_name); |
| 47 | |
| 48 | // wait until start() was called |
| 49 | while (this_thread_obj->thread_status != THREAD_STATUS::RUNNING && |
| 50 | !this_thread_obj->thread_should_finish()) { |
| 51 | std::this_thread::sleep_for(20ms); |
| 52 | } |
| 53 | |
| 54 | // if the "finish flag" has been set in the mean time, don't rerun |
| 55 | while (!this_thread_obj->thread_should_finish()) { |
| 56 | // run |
| 57 | try { |
| 58 | this_thread_obj->run(); |
| 59 | } catch(std::exception& exc) { |
| 60 | log_error("encountered an unhandled exception while running a thread \"$\": $", |
| 61 | get_current_thread_name(), exc.what()); |
| 62 | } catch(...) { |
| 63 | log_error("encountered an unhandled exception while running a thread \"$\"", |
| 64 | get_current_thread_name()); |
| 65 | } |
| 66 | |
| 67 | // again: if the "finish flag" has been set, don't wait, but continue immediately |
| 68 | if (!this_thread_obj->thread_should_finish()) { |
| 69 | // reduce system load and make other locks possible |
| 70 | const size_t thread_delay = this_thread_obj->get_thread_delay(); |
| 71 | if (thread_delay > 0) { |
| 72 | std::this_thread::sleep_for(std::chrono::milliseconds(thread_delay)); |
| 73 | } else { |
| 74 | if (this_thread_obj->get_yield_after_run()) { |
| 75 | // just yield when delay == 0 and "yield after run" flag is set |
| 76 | std::this_thread::yield(); |
| 77 | } |
| 78 | } |
| 79 | } |
| 80 | } |
| 81 | this_thread_obj->set_thread_status(THREAD_STATUS::FINISHED); |
| 82 | |
| 83 | return 0; |
| 84 | } |
| 85 | |
| 86 | void thread_base::finish() { |
| 87 | if (thread_obj != nullptr) { |
nothing calls this directly
no test coverage detected