WorkerCrashLogger:: WorkerCrashLogger(Workers::ptr workers, bool consume_exceptions) : workers_(workers), consume_exceptions_(consume_exceptions) { EXCEPTION_ASSERTX(dynamic_cast<Signal::QtEventWorker::QtEventWorkerFactory*>(workers->workerfactory ()), "WorkerCrashLogger only supports QtEventWorkers"); moveToThread (&thread_); // Remove responsibility for event processing for this when the the thread finishes connect(&thread_, SIGNAL(finished()), SLOT(finished())); thread_.start (); auto ww = workers.write (); // Log any future worker crashes connect(dynamic_cast<Signal::QtEventWorker::QtEventWorkerFactory*>(ww->workerfactory ()), SIGNAL(worker_quit(std::exception_ptr,Signal::ComputingEngine::ptr)), SLOT(worker_quit(std::exception_ptr,Signal::ComputingEngine::ptr))); // Log previous worker crashes. As the new thread owns this, 'check' will // be executed in the new thread. if (consume_exceptions) QTimer::singleShot (0, this, SLOT(check_all_previously_crashed_and_consume())); else QTimer::singleShot (0, this, SLOT(check_all_previously_crashed_without_consuming())); }
void addAndWaitForStop(Workers::ptr workers) { QEventLoop e; // Log any future worker crashes QObject::connect(dynamic_cast<Signal::QtEventWorker::QtEventWorkerFactory*>(workers->workerfactory()), SIGNAL(worker_quit(std::exception_ptr,Signal::ComputingEngine::ptr)), &e, SLOT(quit())); workers.write ()->addComputingEngine(Signal::ComputingEngine::ptr(new Signal::ComputingCpu)); e.exec (); }
int main(void) { long i = 0; worker_pool pool1, pool2; puts("Case 1 : 10 actions (5s) + worker_join"); puts("---------------------------------------"); worker_init(&pool1); for(; i < ACTION_NB; i++) { action_to_do[i].perform = my_action; action_to_do[i].args = (void*) i; worker_add(&pool1, &action_to_do[i]); printf("Action #%li added\n", i); } worker_join(&pool1); puts("All actions terminated"); worker_quit(&pool1); puts("---------------------------------------"); puts("Case 2 : 10 actions (5s) + worker_quit after 1s"); puts("---------------------------------------"); worker_init(&pool2); for(i = 0; i < ACTION_NB; i++) { action_to_do[i].perform = my_action; action_to_do[i].args = (void*) i; worker_add(&pool2, &action_to_do[i]); printf("Action #%li added\n", i); } worker_quit(&pool2); puts("All actions canceled"); puts("---------------------------------------"); return 0; }
void WorkerCrashLogger:: check_all_previously_crashed_without_consuming() { DEBUG TaskInfo ti("check_all_previously_crashed_without_consuming"); auto workers = workers_.read (); const Workers::EngineWorkerMap& workers_map = workers->workers_map(); for(auto i=workers_map.begin (); i != workers_map.end(); ++i) { const Worker::ptr& worker = i->second; if (worker && !worker->isRunning ()) { worker_quit (worker->caught_exception (), i->first); } } }
Signal::Processing::Worker::ptr QtEventWorkerFactory:: make_worker(Signal::ComputingEngine::ptr ce) { QtEventWorker* w; Worker::ptr wp(new WorkerWrapper(w=new QtEventWorker(ce, schedule_, false))); bool a = QObject::connect(w, SIGNAL(finished(std::exception_ptr,Signal::ComputingEngine::ptr)), SIGNAL(worker_quit(std::exception_ptr,Signal::ComputingEngine::ptr))); bool b = connect(notifier_, SIGNAL(wakeup()), w, SLOT(wakeup())); bool c = connect(w, SIGNAL(oneTaskDone()), notifier_, SIGNAL(wakeup())); bool d = connect(w, SIGNAL(finished(std::exception_ptr,Signal::ComputingEngine::ptr)), notifier_, SIGNAL(wakeup())); EXCEPTION_ASSERT(a); EXCEPTION_ASSERT(b); EXCEPTION_ASSERT(c); EXCEPTION_ASSERT(d); w->wakeup (); return wp; }