diff options
author | jstebbins <[email protected]> | 2010-04-09 18:17:51 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2010-04-09 18:17:51 +0000 |
commit | 31916b1e9e513a4791587fb133cb076d61559715 (patch) | |
tree | 1f31a34f7ba2df5f4e726240cecff0e8f77607d0 | |
parent | 50fe6dd131c74884207ed10e660de6351024ef56 (diff) |
LinGui: allow multiple instances of the gui to run
Each instance has a queue named "queue.<pid>". On startup, the gui
opens and locks with lockf a file "ghb.pid.<pid>". Then it searches
for any other ghb.pid.<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.<pid> files.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@3212 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r-- | gtk/src/main.c | 16 | ||||
-rw-r--r-- | gtk/src/presets.c | 146 | ||||
-rw-r--r-- | gtk/src/presets.h | 7 | ||||
-rw-r--r-- | 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 a6a12fc9d..aade07e06 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_("<b><big>Another instance of HandBrake is already running.</big></b>\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 d83038796..7d7e84430 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 a4da4ed74..89f778092 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 24eded5d6..3b91a2464 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); } |