void StopHTTPServer() { LogPrint(BCLog::HTTP, "Stopping HTTP server\n"); if (workQueue) { LogPrint(BCLog::HTTP, "Waiting for HTTP worker threads to exit\n"); workQueue->WaitExit(); delete workQueue; workQueue = nullptr; } if (eventBase) { LogPrint(BCLog::HTTP, "Waiting for HTTP event thread to exit\n"); // Give event loop a few seconds to exit (to send back last RPC responses), then break it // Before this was solved with event_base_loopexit, but that didn't work as expected in // at least libevent 2.0.21 and always introduced a delay. In libevent // master that appears to be solved, so in the future that solution // could be used again (if desirable). // (see discussion in https://github.com/bitcoin/bitcoin/pull/6990) if (threadResult.valid() && threadResult.wait_for(std::chrono::milliseconds(2000)) == std::future_status::timeout) { LogPrintf("HTTP event loop did not exit within allotted time, sending loopbreak\n"); event_base_loopbreak(eventBase); } threadHTTP.join(); } if (eventHTTP) { evhttp_free(eventHTTP); eventHTTP = 0; } if (eventBase) { event_base_free(eventBase); eventBase = 0; } LogPrint(BCLog::HTTP, "Stopped HTTP server\n"); }
/** * Close the task. This will raise in this thread any exception the * task generated in the other thread. Calling this function is * optional, because the destructor will also call this function. * But because it can throw an exception, it is better to call it * explicitly. */ void close() { // If an exception happened in the task, re-throw // it in this thread. This will block if the task // isn't finished. if (m_future.valid()) { m_future.get(); } // Make sure task is done. if (m_thread.joinable()) { m_thread.join(); } }
void on_update(const UpdateEvent & e) override { // Around 60 fps if (fixedTimer.milliseconds().count() >= 16 && turret.fired) { float timestep_ms = fixedTimer.milliseconds().count() / 1000.f; turret.projectile.fixed_update(timestep_ms); std::cout << timestep_ms << std::endl; //std::cout << turret.projectile.p.position << std::endl; fixedTimer.reset(); } cameraController.update(e.timestep_ms); time += e.timestep_ms; shaderMonitor.handle_recompile(); // If a new mesh is ready, retrieve it if (pointerFuture.valid()) { auto status = pointerFuture.wait_for(std::chrono::seconds(0)); if (status != std::future_status::timeout) { auto m = pointerFuture.get(); supershape = m; supershape.pose.position = {0, 2, -2}; pointerFuture = {}; } } // If we don't currently have a background task, begin working on the next mesh if (!pointerFuture.valid() && regeneratePointer) { pointerFuture = std::async([]() { return make_supershape_3d(16, ssM, ssN1, ssN2, ssN3); }); } }
/** * Get the header data from the file. * * @returns Header. * @throws Some form of osmium::io_error if there is an error. */ osmium::io::Header header() { if (m_status == status::error) { throw io_error("Can not get header from reader when in status 'error'"); } try { if (m_header_future.valid()) { m_header = m_header_future.get(); if (m_read_which_entities == osmium::osm_entity_bits::nothing) { m_status = status::eof; } } } catch (...) { close(); m_status = status::error; throw; } return m_header; }
void hook_post_step() { parent_t::hook_post_step(); // includes output this->mem->barrier(); if (this->rank == 0) { // assuring previous async step finished ... #if defined(STD_FUTURE_WORKS) if ( params.async && this->timestep != 0 && // ... but not in first timestep ... ((this->timestep - 1) % this->outfreq != 0) // ... and not after diag call //!((this->timestep-1) == 0 || ((this->timestep-1) % this->outfreq == 0 && (this->timestep-1) >= this->spinup)) // .. and not after diag ) { assert(ftr.valid()); ftr.get(); } else assert(!ftr.valid()); #endif // running synchronous stuff prtcls->step_sync( params.cloudph_opts, make_arrinfo(this->mem->advectee(ix::th)), make_arrinfo(this->mem->advectee(ix::rv)) ); // running asynchronous stuff { using libcloudphxx::lgrngn::particles_t; using libcloudphxx::lgrngn::CUDA; using libcloudphxx::lgrngn::multi_CUDA; #if defined(STD_FUTURE_WORKS) if (params.async) { assert(!ftr.valid()); if(params.backend == multi_CUDA) ftr = std::async( std::launch::async, &particles_t<real_t, multi_CUDA>::step_async, dynamic_cast<particles_t<real_t, multi_CUDA>*>(prtcls.get()), params.cloudph_opts ); else if(params.backend == CUDA) ftr = std::async( std::launch::async, &particles_t<real_t, CUDA>::step_async, dynamic_cast<particles_t<real_t, CUDA>*>(prtcls.get()), params.cloudph_opts ); assert(ftr.valid()); } else #endif prtcls->step_async(params.cloudph_opts); } // performing diagnostics //if (this->timestep == 0 || (this->timestep % this->outfreq == 0 && this->timestep >= this->spinup)) if (this->timestep % this->outfreq == 0) { #if defined(STD_FUTURE_WORKS) if (params.async) { assert(ftr.valid()); ftr.get(); } #endif diag(); } } this->mem->barrier(); }
inline void wait_until_done(std::future<T>& future) { if (future.valid()) { future.get(); } }
inline void check_for_exception(std::future<T>& future) { if (future.valid() && future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) { future.get(); } }
/** * Check task for exceptions. * * If an exception happened in the task, re-throw it in this * thread. This will not do anything if there was no exception. */ void check_for_exception() { if (m_future.valid() && m_future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) { m_future.get(); } }
void gridding_barrier() { if (gridding_future.valid()) gridding_future.get(); //Block until result becomes available }