void force_view_thread_shutdown() { pthread_t current_thread; bool should_wait = false; view_sync.enter(); //destroy all views std::map<int, View*>::const_iterator iter = view_instances.begin(); while (iter != view_instances.end()) { glutDestroyWindow(iter->first); iter++; } view_instances.clear(); //tell thread to finish if (view_thread != NULL) { current_thread = view_thread->thread; view_thread->should_quit = true; view_thread = NULL; } view_sync.leave(); //wait for thread to finish if (should_wait) { glew_initialized = false; pthread_join(current_thread, NULL); } }
/// Does a cross thread call. static int call_in_thread(CTC_FUNC func, void* param) { //check whether the thread is running if not start it view_sync.enter(); if (view_thread == NULL) { ThreadInfo* new_thread_info = NULL; try { new_thread_info = new ThreadInfo(); } catch(std::bad_alloc&) { error("Failed to allocate structure for view thread"); } int err = pthread_create(&new_thread_info->thread, NULL, view_thread_func, new_thread_info); if (err) { delete new_thread_info; error("Failed to create main thread, error: %d", err); } view_thread = new_thread_info; } view_sync.leave(); //make call if (need_safe_call()) { view_sync.enter(); ctc_function = func; ctc_param = param; view_sync.wait_cross_thread_call(); int result = ctc_result; view_sync.leave(); return result; } else return func(param); }
void wait_for_any_key(const char* text) { //wait for key view_sync.enter(); if (view_thread != NULL) { fprintf(stdout, "%s", text); fflush(stdout); view_sync.wait_keypress(); } view_sync.leave(); }
void on_close_stub() { STUB_GET_VIEW(); if (wnd == NULL) return; //call callback wnd->on_close(); //remove view from system view_sync.enter(); RemoveParams params(glutGetWindow(), false); remove_view_in_thread(¶ms); view_sync.signal_close(); view_sync.leave(); }
void wait_for_all_views_close() { pthread_t current_thread; bool should_wait = false; //tell thread to finish view_sync.enter(); if (view_thread != NULL) { current_thread = view_thread->thread; should_wait = true; } view_sync.leave(); //wait for thread to finish if (should_wait) pthread_join(current_thread, NULL); }
void wait_for_all_views_close(const char* text) { pthread_t current_thread; bool should_wait = false; //tell thread to finish view_sync.enter(); if (view_thread != NULL) { current_thread = view_thread->thread; should_wait = true; } view_sync.leave(); //wait for thread to finish if (should_wait) { fprintf(stdout, "%s", text); fflush(stdout); pthread_join(current_thread, NULL); } }
/* view thread function */ static void* view_thread_func(void* param) { ThreadInfo* thread_info = (ThreadInfo*)param; //initize GLUT init_glut(); //run message loop while(1) { //handle glut messages glutMainLoopEvent(); //check whether to quit if (thread_info->should_quit) break; //handle CTC view_sync.enter(); if (ctc_function != NULL) { ctc_result = ctc_function(ctc_param); ctc_function = NULL; view_sync.signal_cross_thread_call(); } view_sync.leave(); //wait for 10 ms #ifdef WIN32 Sleep(10); #else usleep(10*1000); #endif } //cleanup shutdown_glut(); //cleanup delete thread_info; return NULL; }
/// Removes a new view. Function has to be called just from the inside of view thread with a locked sync_view. int remove_view_in_thread(void* remove_params_ptr) { debug_assert(!need_safe_call(), "E remove_view_in_thread called from other thread."); RemoveParams& params = *(RemoveParams*)remove_params_ptr; std::map<int, View*>::iterator found_view = view_instances.find(params.view_id); //debug_assert(found_view != view_instances.end(), "E removing of a view that is not registered"); if (found_view == view_instances.end()) { debug_log("W removing of a view that is not registered\n"); return -1; } //destroy window if requested (it will not be requested when remove is called as a reaction to on_close) if (params.destroy_glut_window) { //remove window from GLUT glutSetWindow(params.view_id); glutSetWindowData(NULL); //prevent stubs from being executed if there is still some message waiting for the window //call on-close event found_view->second->on_close(); //finish removal of window from GLUT glutDestroyWindow(params.view_id); } //remove from structures view_instances.erase(found_view); //thread cleanup if (view_instances.size() == 0) { view_thread->should_quit = true; view_thread = NULL; //signal all events view_sync.signal_close(); view_sync.signal_keypress(); view_sync.signal_drawing_finished(); } return 0; }