diff --git a/src/control/control.c b/src/control/control.c index 1effb5c2f064..869077ad3cb0 100644 --- a/src/control/control.c +++ b/src/control/control.c @@ -203,7 +203,6 @@ void dt_control_init(const gboolean withgui) s->input_drivers = NULL; dt_atomic_set_int(&s->quitting, 0); dt_atomic_set_int(&s->pending_jobs, 0); - dt_atomic_set_int(&s->running_jobs, 0); s->cups_started = FALSE; dt_action_define_fallback(DT_ACTION_TYPE_IOP, &dt_action_def_iop); @@ -221,7 +220,6 @@ void dt_control_init(const gboolean withgui) // same thread as init s->gui_thread = pthread_self(); - // s->last_expose_time = dt_get_wtime(); s->log_pos = s->log_ack = 0; s->busy = 0; s->log_message_timeout_id = 0; @@ -284,11 +282,6 @@ void dt_control_change_cursor(dt_cursor_t curs) via DT_CONTROL_STATE_CLEANUP before doing so. */ -gboolean dt_control_running() -{ - return darktable.control && dt_atomic_get_int(&darktable.control->running) == DT_CONTROL_STATE_RUNNING; -} - void dt_control_quit() { // Make sure we proceed further only if control is running diff --git a/src/control/control.h b/src/control/control.h index 0447b53b06d8..b1118be15a2b 100644 --- a/src/control/control.h +++ b/src/control/control.h @@ -175,13 +175,11 @@ typedef struct dt_control_t // gui settings dt_pthread_mutex_t global_mutex, image_mutex; - double last_expose_time; // job management dt_atomic_int running; dt_atomic_int quitting; dt_atomic_int pending_jobs; - dt_atomic_int running_jobs; gboolean cups_started; gboolean export_scheduled; dt_pthread_mutex_t queue_mutex, cond_mutex; @@ -249,7 +247,20 @@ void dt_control_cleanup(const gboolean withgui); void dt_control_quit(void); /** get threadsafe running state. */ -gboolean dt_control_running(void); +#define dt_control_running() dt_control_running_with_caller(__FILE__, __LINE__, __FUNCTION__) +static inline gboolean dt_control_running_with_caller(const char *file, + const int line, + const char *function) +{ + dt_control_t *c = darktable.control; + if(!c) + { + dt_print(DT_DEBUG_ALWAYS, "darktable.control is undefined in '%s': `%s:%d`", function, file, line); + return FALSE; + } + else + return dt_atomic_get_int(&c->running) == DT_CONTROL_STATE_RUNNING; +} // thread-safe interface between core and gui. // is the locking really needed? diff --git a/src/control/jobs.c b/src/control/jobs.c index 24a82dfaaf61..731991da567a 100644 --- a/src/control/jobs.c +++ b/src/control/jobs.c @@ -511,12 +511,8 @@ static void *_control_work_res(void *ptr) worker_thread_parameters_t *params = (worker_thread_parameters_t *)ptr; dt_control_t *s = params->self; threadid = params->threadid; - char name[16] = {0}; - snprintf(name, sizeof(name), "worker res %d", threadid); - dt_pthread_setname(name); free(params); const int32_t threadid_res = _control_get_threadid_res(); - dt_atomic_add_int(&s->running_jobs, 1); while(dt_control_running()) { // dt_print(DT_DEBUG_CONTROL, "[control_work] %d", threadid_res); @@ -539,7 +535,6 @@ static void *_control_worker_kicker(void *ptr) { dt_control_t *control = (dt_control_t *)ptr; dt_pthread_setname("kicker"); - dt_atomic_add_int(&control->running_jobs, 1); while(dt_control_running()) { sleep(2); @@ -558,12 +553,7 @@ static void *_control_work(void *ptr) worker_thread_parameters_t *params = (worker_thread_parameters_t *)ptr; dt_control_t *control = params->self; threadid = params->threadid; - char name[16] = {0}; - snprintf(name, sizeof(name), "worker %d", threadid); - dt_pthread_setname(name); free(params); - - dt_atomic_add_int(&control->running_jobs, 1); while(dt_control_running()) { if(_control_run_job(control)) @@ -651,37 +641,9 @@ void dt_control_jobs_init() if(err != 0) { - /* FIXME can we handle this better? - Should we unset control->running here? requires further investigation - on how to join or avoid rogue threads - */ + /* FIXME can we handle this better? */ dt_print(DT_DEBUG_ALWAYS, "[dt_control_jobs_init] ERROR STARTING THREADS, PROBLEMS AHEAD"); } - else // no errors reported so we test & wait - { - const int requested = control->num_threads + 1 + DT_CTL_WORKER_RESERVED; - int running = 0; - for(int i = 0; i < 1000; i++) - { - running = dt_atomic_get_int(&control->running_jobs); - dt_print(DT_DEBUG_CONTROL, "[dt_control_jobs_init] %d of %d threads running", running, requested); - if(running == requested) break; - g_usleep(1000); // let's wait for up to 1sec for OS dispatching the pthreads - } - if(running != requested) - dt_print(DT_DEBUG_ALWAYS, "[dt_control_jobs_init] ERROR STARTED %d THREADS of %d, PROBLEMS AHEAD", - running, requested); - } -} - -gboolean dt_control_all_running() -{ - if(!dt_control_running()) - return FALSE; - - dt_control_t *control = darktable.control; - const int requested = control->num_threads + 1 + DT_CTL_WORKER_RESERVED; - return dt_atomic_get_int(&control->running_jobs) == requested; } void dt_control_jobs_cleanup() diff --git a/src/control/jobs.h b/src/control/jobs.h index 3e1161701c5f..2fc46ac1c23d 100644 --- a/src/control/jobs.h +++ b/src/control/jobs.h @@ -82,7 +82,6 @@ double dt_control_job_get_progress(const dt_job_t *job); void dt_control_jobs_init(void); void dt_control_jobs_cleanup(void); int dt_control_jobs_pending(void); -gboolean dt_control_all_running(void); gboolean dt_control_add_job(dt_job_queue_t queue_id, dt_job_t *job); gboolean dt_control_add_job_res(dt_job_t *job, const int32_t res); diff --git a/src/gui/gtk.c b/src/gui/gtk.c index 7816660a01d8..2e70fea4f88e 100644 --- a/src/gui/gtk.c +++ b/src/gui/gtk.c @@ -1278,9 +1278,11 @@ int dt_gui_theme_init(dt_gui_gtk_t *gui) int dt_gui_gtk_init(dt_gui_gtk_t *gui) { - /* lets zero mem */ - memset(gui, 0, sizeof(dt_gui_gtk_t)); - + /* Note: + *gui has been calloced in dt_init() so no need to clear via memset + also it got some changes already, let's keep them + memset(gui, 0, sizeof(dt_gui_gtk_t)); + */ dt_pthread_mutex_init(&gui->mutex, NULL); // force gtk3 to use normal scroll bars instead of the popup @@ -1603,6 +1605,15 @@ int dt_gui_gtk_init(dt_gui_gtk_t *gui) darktable.gui->focus_peaking_button, &dt_action_def_toggle); dt_shortcut_register(ac, 0, 0, GDK_KEY_f, GDK_CONTROL_MASK | GDK_SHIFT_MASK); + // give Gtk a chance to update the screen; we need to let the event + // processing run several times for the window to actually be + // fully displayed/updated + for(int i = 0; i < 5; i++) + { + g_usleep(1000); + dt_gui_process_events(); + } + return 0; } @@ -1625,7 +1636,7 @@ void dt_gui_gtk_run(dt_gui_gtk_t *gui) dt_osx_focus_window(); #endif /* start the event loop */ - if(dt_control_all_running()) + if(dt_control_running()) { g_atomic_int_set(&darktable.gui_running, 1); gtk_main();