Пример #1
0
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);
  }
}
Пример #2
0
/// 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);
}
Пример #3
0
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();
}
Пример #4
0
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(&params);
  view_sync.signal_close();
  view_sync.leave();
}
Пример #5
0
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);
}
Пример #6
0
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);
  }
}
Пример #7
0
/* 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;
}
Пример #8
0
/// 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;
}