summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2010-04-09 18:17:51 +0000
committerjstebbins <[email protected]>2010-04-09 18:17:51 +0000
commit31916b1e9e513a4791587fb133cb076d61559715 (patch)
tree1f31a34f7ba2df5f4e726240cecff0e8f77607d0
parent50fe6dd131c74884207ed10e660de6351024ef56 (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.c16
-rw-r--r--gtk/src/presets.c146
-rw-r--r--gtk/src/presets.h7
-rw-r--r--gtk/src/queuehandler.c14
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);
}