scheduler_impl_t::wait_result_t scheduler_impl_t::wait_queue(spinlock_t* queue_lock, duration_t* timeout) { ev_timer timer_timeout; watcher_data_t watcher_data(FIBER_IMPL); deferred_unlock_t deferred(queue_lock); ev_tstamp start_wait; if(timeout) { start_wait = ev_now(ev_loop_); ev_init((ev_watcher*)&timer_timeout, switch_to_cb); ev_timer_set(&timer_timeout, timeout->count(), 0.0); ev_timer_start(ev_loop_, &timer_timeout); timer_timeout.data = &watcher_data; } FIBER_IMPL->yield(&deferred); unlink_activate(FIBER_IMPL); if(timeout) { *timeout -= duration_t(ev_now(ev_loop_) - start_wait); ev_timer_stop(ev_loop_, &timer_timeout); } if(timeout && (watcher_data.events & EV_TIMER)) { return TIMEDOUT; } else { return READY; } }
int App::run() { try{init(); m_running = GL_TRUE;} catch(std::exception &e){LOG_ERROR<<e.what();} double timeStamp = 0.0; // Main loop while( m_running ) { // update application time timeStamp = getApplicationTime(); // poll io_service if no seperate worker-threads exist if(!m_main_queue.get_num_threads()) m_main_queue.io_service().poll(); // poll input events pollEvents(); // time elapsed since last frame double time_delta = timeStamp - m_lastTimeStamp; // call update callback update(time_delta); m_lastTimeStamp = timeStamp; if(needs_redraw()) { // call draw callback draw_internal(); // Swap front and back rendering buffers swapBuffers(); } // perform fps-timing timing(timeStamp); // Check if ESC key was pressed or window was closed or whatever m_running = checkRunning(); // fps managment float current_fps = 1.f / time_delta; if(current_fps > m_max_fps) { double sleep_secs = std::max(0.0, (1.0 / m_max_fps - time_delta)); this_thread::sleep_for(duration_t(sleep_secs)); } } // manage tearDown, save stuff etc. tearDown(); return EXIT_SUCCESS; }
scheduler_impl_t::wait_result_t scheduler_impl_t::wait_timeout(duration_t* timeout) { assert(timeout); ev_timer timer_ready; watcher_data_t watcher_data(FIBER_IMPL); ev_init((ev_watcher*)&timer_ready, switch_to_cb); ev_timer_set(&timer_ready, timeout->count(), 0.0); ev_timer_start(ev_loop_, &timer_ready); timer_ready.data = &watcher_data; ev_tstamp start_wait = ev_now(ev_loop_); FIBER_IMPL->yield(); *timeout -= duration_t(ev_now(ev_loop_) - start_wait); ev_timer_stop(ev_loop_, &timer_ready); return READY; }
scheduler_impl_t::wait_result_t scheduler_impl_t::wait_io(int fd, int events, duration_t* timeout) { ev_io io_ready; ev_timer timer_timeout; watcher_data_t watcher_data(FIBER_IMPL); ev_init((ev_watcher*)&io_ready, switch_to_cb); ev_io_set(&io_ready, fd, events); io_ready.data = &watcher_data; ev_io_start(ev_loop_, &io_ready); if(timeout) { ev_init((ev_watcher*)&timer_timeout, switch_to_cb); ev_timer_set(&timer_timeout, timeout->count(), 0.0); timer_timeout.data = &watcher_data; ev_timer_start(ev_loop_, &timer_timeout); } ev_tstamp start_wait = ev_now(ev_loop_); FIBER_IMPL->yield(); if(timeout) *timeout -= duration_t(ev_now(ev_loop_) - start_wait); ev_io_stop(ev_loop_, &io_ready); if(timeout) { ev_timer_stop(ev_loop_, &timer_timeout); } if(watcher_data.events & EV_ERROR) { return ERROR; } else if(watcher_data.events & EV_TIMER) { return TIMEDOUT; } else { return READY; } }