aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2021-04-01 11:38:44 +0200
committerThomas White <taw@physics.org>2021-04-01 15:08:14 +0200
commitc5f62f02be9fd29eb3f8f7831ac98617752ea789 (patch)
tree3f6c2512ad9cc233328e30aaa2f6f0c27fcec16c
parentbb383134d7f2d15578b77186f5b35e6b8c344b71 (diff)
GUI: Clean up old tasks when infobar is removed
-rw-r--r--src/crystfel_gui.c61
-rw-r--r--src/gui_backend_local.c9
-rw-r--r--src/gui_backend_slurm.c9
-rw-r--r--src/gui_project.c2
-rw-r--r--src/gui_project.h6
5 files changed, 75 insertions, 12 deletions
diff --git a/src/crystfel_gui.c b/src/crystfel_gui.c
index 06d4f866..07626dbb 100644
--- a/src/crystfel_gui.c
+++ b/src/crystfel_gui.c
@@ -175,10 +175,12 @@ const char *selected_result(struct crystfelproject *proj)
* (i.e. merging) */
static int have_running_jobs(struct crystfelproject *proj)
{
- int i;
+ GSList *item = proj->tasks;
- for ( i=0; i<proj->n_running_tasks; i++ ) {
- if ( proj->tasks[i].running ) return 1;
+ while ( item != NULL ) {
+ struct gui_task *task = item->data;
+ if ( task->running ) return 1;
+ item = item->next;
}
return 0;
@@ -977,18 +979,49 @@ int main(int argc, char *argv[])
}
+struct infobar_data
+{
+ struct crystfelproject *proj;
+ struct gui_task *task;
+};
+
+
+static void free_ib_callback_params(gpointer cbvals,
+ GClosure *closure)
+{
+ free(cbvals);
+}
+
+
+static void remove_task(struct crystfelproject *proj,
+ struct gui_task *task)
+{
+ if ( task->running ) {
+ ERROR("Attempt to remove a running task!\n");
+ return;
+ }
+
+ if ( task->backend->free_task != NULL ) {
+ task->backend->free_task(task->job_priv);
+ }
+ free(task);
+
+ proj->tasks = g_slist_remove(proj->tasks, task);
+}
+
+
static void infobar_response_sig(GtkInfoBar *infobar, gint resp,
gpointer data)
{
- struct gui_task *task = data;
+ struct infobar_data *ibdata = data;
if ( resp == GTK_RESPONSE_CANCEL ) {
- task->backend->cancel_task(task->job_priv);
+ ibdata->task->backend->cancel_task(ibdata->task->job_priv);
} else if ( resp == GTK_RESPONSE_CLOSE ) {
gtk_widget_destroy(GTK_WIDGET(infobar));
- /* FIXME: Remove task from list */
+ remove_task(ibdata->proj, ibdata->task);
} else {
ERROR("Unrecognised infobar response!\n");
@@ -1030,12 +1063,16 @@ void add_running_task(struct crystfelproject *proj,
void *job_priv)
{
struct gui_task *task;
+ struct infobar_data *ibdata;
GtkWidget *bar_area;
- task = &proj->tasks[proj->n_running_tasks++];
+ task = malloc(sizeof(struct gui_task));
+ if ( task == NULL ) return;
+
task->job_priv = job_priv;
task->backend = backend;
task->running = 1;
+ proj->tasks = g_slist_append(proj->tasks, task);
/* Progress info bar */
task->info_bar = gtk_info_bar_new();
@@ -1061,8 +1098,14 @@ void add_running_task(struct crystfelproject *proj,
gtk_progress_bar_set_show_text(GTK_PROGRESS_BAR(task->progress_bar),
TRUE);
- g_signal_connect(G_OBJECT(task->info_bar), "response",
- G_CALLBACK(infobar_response_sig), task);
+ ibdata = malloc(sizeof(struct infobar_data));
+ if ( ibdata != NULL ) {
+ ibdata->proj = proj;
+ ibdata->task = task;
+ g_signal_connect_data(G_OBJECT(task->info_bar), "response",
+ G_CALLBACK(infobar_response_sig), ibdata,
+ free_ib_callback_params, 0);
+ }
gtk_widget_show_all(task->info_bar);
diff --git a/src/gui_backend_local.c b/src/gui_backend_local.c
index 96d6c6b3..545ac776 100644
--- a/src/gui_backend_local.c
+++ b/src/gui_backend_local.c
@@ -79,6 +79,14 @@ struct local_job
};
+static void free_task(void *job_priv)
+{
+ struct local_job *job = job_priv;
+ g_object_unref(job->workdir);
+ free(job->stderr_filename);
+}
+
+
static void watch_subprocess(GPid pid, gint status, gpointer vp)
{
struct local_job *job = vp;
@@ -677,6 +685,7 @@ int make_local_backend(struct crystfel_backend *be)
be->friendly_name = "Local (run on this computer)";
be->cancel_task = cancel_task;
+ be->free_task = free_task;
be->task_status = get_task_status;
be->make_indexing_parameters_widget = make_indexing_parameters_widget;
diff --git a/src/gui_backend_slurm.c b/src/gui_backend_slurm.c
index ed49c4c6..1da344ce 100644
--- a/src/gui_backend_slurm.c
+++ b/src/gui_backend_slurm.c
@@ -222,6 +222,14 @@ static int get_task_status(void *job_priv,
}
+static void free_task(void *job_priv)
+{
+ struct slurm_job *job = job_priv;
+ g_object_unref(job->workdir);
+ free(job->stderr_filename);
+}
+
+
static void cancel_task(void *job_priv)
{
char jobid[128];
@@ -1050,6 +1058,7 @@ int make_slurm_backend(struct crystfel_backend *be)
be->friendly_name = "SLURM";
be->cancel_task = cancel_task;
+ be->free_task = free_task;
be->task_status = get_task_status;
be->make_indexing_parameters_widget = make_indexing_parameters_widget;
diff --git a/src/gui_project.c b/src/gui_project.c
index fba38b7c..920bc310 100644
--- a/src/gui_project.c
+++ b/src/gui_project.c
@@ -1093,7 +1093,7 @@ void default_project(struct crystfelproject *proj)
proj->indexing_opts = NULL;
proj->merging_opts = NULL;
proj->ambi_opts = NULL;
- proj->n_running_tasks = 0;
+ proj->tasks = NULL;
proj->indexing_new_job_title = NULL;
proj->merging_new_job_title = NULL;
proj->ambi_new_job_title = NULL;
diff --git a/src/gui_project.h b/src/gui_project.h
index e4daeb8d..d698e720 100644
--- a/src/gui_project.h
+++ b/src/gui_project.h
@@ -157,6 +157,9 @@ struct crystfel_backend {
/* Called to ask the backend to cancel the job */
void (*cancel_task)(void *job_priv);
+ /* Called to ask the backend to free any resources in the job record */
+ void (*free_task)(void *job_priv);
+
/* Called to get the status of a task */
int (*task_status)(void *job_priv,
int *running,
@@ -308,8 +311,7 @@ struct crystfelproject {
struct crystfel_backend *backends;
int n_backends;
- struct gui_task tasks[MAX_RUNNING_TASKS];
- int n_running_tasks;
+ GSList *tasks;
struct gui_indexing_result *results;
int n_results;