aboutsummaryrefslogtreecommitdiffstats
path: root/g13/runner.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--g13/runner.c60
1 files changed, 51 insertions, 9 deletions
diff --git a/g13/runner.c b/g13/runner.c
index d88b69b98..27d03702a 100644
--- a/g13/runner.c
+++ b/g13/runner.c
@@ -40,9 +40,12 @@ struct runner_s
int spawned; /* True if runner_spawn has been called. */
pth_t threadid; /* The TID of the runner thread. */
+ runner_t next_running; /* Builds a list of all running threads. */
+ int canceled; /* Set if a cancel has already been send once. */
int cancel_flag; /* If set the thread should terminate itself. */
+
/* We use a reference counter to know when it is safe to remove the
object. Lackiong an explicit ref fucntion this counter will take
only these two values:
@@ -66,8 +69,9 @@ struct runner_s
};
-/* Avariabale to track the number of active runner threads. */
-static unsigned int thread_count;
+/* The head of the list of all running threads. */
+static runner_t running_threads;
+
@@ -114,7 +118,12 @@ check_already_spawned (runner_t runner, const char *funcname)
unsigned int
runner_get_threads (void)
{
- return thread_count;
+ unsigned int n = 0;
+ runner_t r;
+
+ for (r = running_threads; r; r = r->next_running)
+ n++;
+ return n;
}
@@ -240,7 +249,7 @@ static void *
runner_thread (void *arg)
{
runner_t runner = arg;
- gpg_error_t err;
+ gpg_error_t err = 0;
log_debug ("starting runner thread\n");
/* If a status_fp is available, the thread's main task is to read
@@ -257,7 +266,6 @@ runner_thread (void *arg)
estream_t fp = runner->status_fp;
pos = 0;
- err = 0;
cont_line = 0;
while (!err && !runner->cancel_flag && (c=es_getc (fp)) != EOF)
{
@@ -322,9 +330,22 @@ runner_thread (void *arg)
/* Get rid of the runner object (note: it is refcounted). */
log_debug ("runner thread releasing runner ...\n");
+ {
+ runner_t r, rprev;
+
+ for (r = running_threads, rprev = NULL; r; rprev = r, r = r->next_running)
+ if (r == runner)
+ {
+ if (!rprev)
+ running_threads = r->next_running;
+ else
+ rprev->next_running = r->next_running;
+ r->next_running = NULL;
+ break;
+ }
+ }
runner_release (runner);
log_debug ("runner thread runner released\n");
- thread_count--;
return NULL;
}
@@ -374,14 +395,14 @@ runner_spawn (runner_t runner)
}
/* The scheduler has not yet kicked in, thus we can safely set the
spawned flag and the tid. */
- thread_count++;
runner->spawned = 1;
runner->threadid = tid;
+ runner->next_running = running_threads;
+ running_threads = runner;
+
pth_attr_destroy (tattr);
/* The runner thread is now runnable. */
-
-
return 0;
}
@@ -391,8 +412,10 @@ runner_spawn (runner_t runner)
void
runner_cancel (runner_t runner)
{
+ /* Warning: runner_cancel_all has knowledge of this code. */
if (runner->spawned)
{
+ runner->canceled = 1; /* Mark that we canceled this one already. */
/* FIXME: This does only work if the thread emits status lines. We
need to change the trhead to wait on an event. */
runner->cancel_flag = 1;
@@ -402,6 +425,25 @@ runner_cancel (runner_t runner)
}
+/* Cancel all runner threads. */
+void
+runner_cancel_all (void)
+{
+ runner_t r;
+
+ do
+ {
+ for (r = running_threads; r; r = r->next_running)
+ if (r->spawned && !r->canceled)
+ {
+ runner_cancel (r);
+ break;
+ }
+ }
+ while (r);
+}
+
+
/* Send a line of data down to the engine. This line may not contain
a binary Nul or a LF character. This function is used by the
engine's handler. */