From 38411ed3d2e33bd434f7f255279924eba7c55e46 Mon Sep 17 00:00:00 2001 From: jstebbins Date: Fri, 9 Apr 2010 18:17:51 +0000 Subject: [PATCH] LinGui: allow multiple instances of the gui to run Each instance has a queue named "queue.". On startup, the gui opens and locks with lockf a file "ghb.pid.". Then it searches for any other ghb.pid. files that exist that are not locked. If it finds one, then some instance of ghb exited and may have left behind a queue. Try to reload it. If there are no items in the queue, continue looking for unlocked ghb.pid. files. git-svn-id: svn://localhost/HandBrake/trunk@3212 b64f7644-9d1e-0410-96f1-a4d463321fa5 --- gtk/src/main.c | 16 +----- gtk/src/presets.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++++- gtk/src/presets.h | 7 ++- gtk/src/queuehandler.c | 14 ++++- 4 files changed, 162 insertions(+), 21 deletions(-) diff --git a/gtk/src/main.c b/gtk/src/main.c index a6a12fc9..aade07e0 100644 --- a/gtk/src/main.c +++ b/gtk/src/main.c @@ -698,21 +698,7 @@ main (int argc, char *argv[]) ghb_hal_init(); #endif - if (!ghb_lock_file("queue_lock")) - { - const gchar *markup = - N_("Another instance of HandBrake is already running.\n" - "\n" - "Only one instance of HandBrake may run.\n"); - GtkWidget *dialog = gtk_message_dialog_new_with_markup(NULL, - GTK_DIALOG_MODAL, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - _(markup)); - gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); - exit(EXIT_FAILURE); - } + ghb_write_pid_file(); ud = g_malloc0(sizeof(signal_user_data_t)); ud->debug = ghb_debug; g_log_set_handler (NULL, G_LOG_LEVEL_DEBUG, debug_log_handler, ud); diff --git a/gtk/src/presets.c b/gtk/src/presets.c index d8303879..7d7e8443 100644 --- a/gtk/src/presets.c +++ b/gtk/src/presets.c @@ -1151,6 +1151,104 @@ ghb_lock_file(const gchar *name) #endif } +void +ghb_write_pid_file() +{ +#if !defined(_WIN32) + gchar *config, *path; + pid_t pid; + FILE *fp; + int fd, lock; + + pid = getpid(); + + config = ghb_get_user_config_dir(NULL); + path = g_strdup_printf ("%s/ghb.pid.%d", config, pid); + + fp = g_fopen(path, "w"); + fprintf(fp, "%d\n", pid); + fclose(fp); + + fd = open(path, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); + lock = lockf(fd, F_TLOCK, 0); + + g_free(config); + g_free(path); +#endif +} + +void +ghb_unlink_pid_file(int pid) +{ + gchar *config, *path; + + config = ghb_get_user_config_dir(NULL); + path = g_strdup_printf ("%s/ghb.pid.%d", config, pid); + + if (g_file_test(path, G_FILE_TEST_IS_REGULAR)) + { + g_unlink(path); + } + + g_free(config); + g_free(path); +} + +int +ghb_find_pid_file() +{ + const gchar *file; + gchar *config; + + config = ghb_get_user_config_dir(NULL); + + if (g_file_test(config, G_FILE_TEST_IS_DIR)) + { + GDir *gdir = g_dir_open(config, 0, NULL); + file = g_dir_read_name(gdir); + while (file) + { + if (strncmp(file, "ghb.pid.", 8) == 0) + { + gchar *path; + int fd, lock = 1; + pid_t my_pid; + int pid; + + sscanf(file, "ghb.pid.%d", &pid); + my_pid = getpid(); + if (my_pid == pid) + { + file = g_dir_read_name(gdir); + continue; + } + + path = g_strdup_printf("%s/%s", config, file); + fd = g_open(path, O_RDWR); + if (fd >= 0) + { + lock = lockf(fd, F_TLOCK, 0); + } + if (lock == 0) + { + close(fd); + g_dir_close(gdir); + g_unlink(path); + g_free(path); + g_free(config); + return pid; + } + g_free(path); + close(fd); + } + file = g_dir_read_name(gdir); + } + g_dir_close(gdir); + } + g_free(config); + return -1; +} + static void remove_plist(const gchar *name) { @@ -1806,19 +1904,61 @@ remove_std_presets(signal_user_data_t *ud) void ghb_save_queue(GValue *queue) { - store_plist(queue, "queue"); + pid_t pid; + char *path; + + pid = getpid(); + path = g_strdup_printf ("queue.%d", pid); + store_plist(queue, path); + g_free(path); } GValue* ghb_load_queue() { - return load_plist("queue"); + GValue *queue; + pid_t pid; + char *path; + + pid = getpid(); + path = g_strdup_printf ("queue.%d", pid); + queue = load_plist(path); + g_free(path); + return queue; +} + +GValue* +ghb_load_old_queue(int pid) +{ + GValue *queue; + char *path; + + path = g_strdup_printf ("queue.%d", pid); + queue = load_plist(path); + g_free(path); + return queue; +} + +void +ghb_remove_old_queue_file(int pid) +{ + char *path; + + path = g_strdup_printf ("queue.%d", pid); + remove_plist(path); + g_free(path); } void ghb_remove_queue_file() { - remove_plist("queue"); + pid_t pid; + char *path; + + pid = getpid(); + path = g_strdup_printf ("queue.%d", pid); + remove_plist(path); + g_free(path); } typedef struct diff --git a/gtk/src/presets.h b/gtk/src/presets.h index a4da4ed7..89f77809 100644 --- a/gtk/src/presets.h +++ b/gtk/src/presets.h @@ -27,7 +27,9 @@ void ghb_prefs_save(GValue *settings); void ghb_pref_save(GValue *settings, const gchar *key); void ghb_save_queue(GValue *queue); GValue* ghb_load_queue(); -void ghb_remove_queue_file(void);; +GValue* ghb_load_old_queue(int pid); +void ghb_remove_queue_file(void); +void ghb_remove_old_queue_file(int pid); gchar* ghb_get_user_config_dir(gchar *subdir); void ghb_settings_to_ui(signal_user_data_t *ud, GValue *dict); void ghb_clear_presets_selection(signal_user_data_t *ud); @@ -42,5 +44,8 @@ void ghb_prefs_store(void); void ghb_pref_set(GValue *settings, const gchar *key); gboolean ghb_lock_file(const gchar *name); void ghb_refresh_preset(signal_user_data_t *ud); +int ghb_find_pid_file(); +void ghb_unlink_pid_file(int pid); +void ghb_write_pid_file(); #endif // _GHB_PRESETS_H_ diff --git a/gtk/src/queuehandler.c b/gtk/src/queuehandler.c index 24eded5d..3b91a246 100644 --- a/gtk/src/queuehandler.c +++ b/gtk/src/queuehandler.c @@ -1259,13 +1259,20 @@ ghb_reload_queue(signal_user_data_t *ud) GValue *queue; gint unfinished = 0; gint count, ii; + gint pid; gint status; GValue *settings; gchar *message; g_debug("ghb_reload_queue"); - queue = ghb_load_queue(); +find_pid: + pid = ghb_find_pid_file(); + if (pid < 0) + return FALSE; + + queue = ghb_load_old_queue(pid); + ghb_remove_old_queue_file(pid); // Look for unfinished entries count = ghb_array_len(queue); for (ii = 0; ii < count; ii++) @@ -1277,6 +1284,9 @@ ghb_reload_queue(signal_user_data_t *ud) unfinished++; } } + if (!unfinished) + goto find_pid; + if (unfinished) { message = g_strdup_printf( @@ -1314,11 +1324,11 @@ ghb_reload_queue(signal_user_data_t *ud) add_to_queue_list(ud, settings, NULL); } ghb_queue_buttons_grey(ud); + ghb_save_queue(ud->queue); } else { ghb_value_free(queue); - ghb_remove_queue_file(); } g_free(message); } -- 2.11.0