static int mydrv_worker(void* unused){ DECLARE_WAITQUEUE(wait, current); void* (worker_fucn)(void*); void* worker_data; WORK *mydrv_work; set_current_state(TASK_INTERRUPTIBLE); while(1){ add_wait_queue(&mydrv_wq.todo, &wait); if(list_empty(&mydrv_wq.mydrv_worklist)){ //if nothing todo schedlue(); } else set_current_state(TASK_RUNNING); //remove itself frome waitqueue remove_wait_queue(&mydrv_wq.todo, &wait); spin_lock(&mydrv_wq.lock); while(!list_empty(&mydrv_wq.mydrv_worklist)){ //get a workitem mydrv_work = list_entry(&mydrv.mydrv_worklist.next, struct _mydrv_work, mydrv_workitem); worker_func = mydrv_work->worker_func; worker_data = mydrv-work->worker_data; //this node has been processed, throw it list_del(&mydev.mydrv_worklist.next); free(mydrv_work); spin_unlock(&mydrv_wq.lock); //execute the work function in this node worker_func(worker_data); spin_lock(&mydrv_wq.lock); } spin_unlock(&mydrv_wq.lock); set_current_state(TASK_INTERRUPTIBLE); } set_current_state(TASK_RUNNING); return 0; }
Console::Console ( std::function<void (String)> callback, Nullable<Word> output_max, std::function<void (std::exception_ptr)> panic ) : callback(std::move(callback)), output_max(std::move(output_max)), barrier(2), panic(std::move(panic)) { // Prepare events queued=create_event(); try { stop=create_event(); try { // Start worker t=Thread([this] () mutable { worker_func(); }); // Wait for worker thread // to start barrier.Enter(); // Did startup fail? if (except) { // YES, join worker and // throw t.Join(); std::rethrow_exception(except); } } catch (...) { CloseHandle(stop); throw; } } catch (...) { CloseHandle(queued); throw; } }
DNSHandler::DNSHandler (PanicType panic) : stop(false), panic(std::move(panic)) { // Setup the completion callback complete=[this] (Query * q, bool) mutable noexcept { lock.Execute([&] () mutable { queries.erase(q); }); }; // Check panic callback, if it's empty, // default it to std::abort if (!panic) panic=[] (std::exception_ptr) { std::abort(); }; // Initialize libcares auto result=ares_library_init(ARES_LIB_INIT_ALL); if (result!=0) raise(result); try { // Prepare an asynchronous resolver // channel if ((result=ares_init(&channel))!=0) raise(result); try { // Create worker thread thread=Thread([this] () mutable { worker_func(); }); } catch (...) { ares_destroy(channel); throw; } } catch (...) { ares_library_cleanup(); throw; } }