mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-13 22:21:09 +02:00
dirmngr: Add a background task framework.
* dirmngr/workqueue.c: New. * dirmngr/Makefile.am (dirmngr_SOURCES): Add new file. * dirmngr/server.c (server_local_s): New field session_id. (cmd_wkd_get): Add a task. (task_check_wkd_support): New stub function. (cmd_getinfo): New sub-commands "session_id" and "workqueue". (start_command_handler): Add arg session_id and store it in SERVER_LOCAL. (dirmngr_status_helpf): New. * dirmngr/dirmngr.h (wqtask_t): New type. * dirmngr/dirmngr.c (main): Pass 0 as session_id to start_command_handler. (start_connection_thread): Introduce a session_id and pass it to start_command_handler. Run post session tasks. (housekeeping_thread): Run global workqueue tasks. -- Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
26f08343fb
commit
96a4fbecd1
@ -60,6 +60,7 @@ noinst_HEADERS = dirmngr.h crlcache.h crlfetch.h misc.h
|
|||||||
dirmngr_SOURCES = dirmngr.c dirmngr.h server.c crlcache.c crlfetch.c \
|
dirmngr_SOURCES = dirmngr.c dirmngr.h server.c crlcache.c crlfetch.c \
|
||||||
certcache.c certcache.h \
|
certcache.c certcache.h \
|
||||||
domaininfo.c \
|
domaininfo.c \
|
||||||
|
workqueue.c \
|
||||||
loadswdb.c \
|
loadswdb.c \
|
||||||
cdb.h cdblib.c misc.c dirmngr-err.h \
|
cdb.h cdblib.c misc.c dirmngr-err.h \
|
||||||
ocsp.c ocsp.h validate.c validate.h \
|
ocsp.c ocsp.h validate.c validate.h \
|
||||||
|
@ -1134,7 +1134,7 @@ main (int argc, char **argv)
|
|||||||
cert_cache_init (hkp_cacert_filenames);
|
cert_cache_init (hkp_cacert_filenames);
|
||||||
crl_cache_init ();
|
crl_cache_init ();
|
||||||
http_register_netactivity_cb (netactivity_action);
|
http_register_netactivity_cb (netactivity_action);
|
||||||
start_command_handler (ASSUAN_INVALID_FD);
|
start_command_handler (ASSUAN_INVALID_FD, 0);
|
||||||
shutdown_reaper ();
|
shutdown_reaper ();
|
||||||
}
|
}
|
||||||
#ifndef HAVE_W32_SYSTEM
|
#ifndef HAVE_W32_SYSTEM
|
||||||
@ -1939,7 +1939,10 @@ housekeeping_thread (void *arg)
|
|||||||
network_activity_seen = 0;
|
network_activity_seen = 0;
|
||||||
if (opt.allow_version_check)
|
if (opt.allow_version_check)
|
||||||
dirmngr_load_swdb (&ctrlbuf, 0);
|
dirmngr_load_swdb (&ctrlbuf, 0);
|
||||||
|
workqueue_run_global_tasks (&ctrlbuf, 1);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
workqueue_run_global_tasks (&ctrlbuf, 0);
|
||||||
|
|
||||||
dirmngr_deinit_default_ctrl (&ctrlbuf);
|
dirmngr_deinit_default_ctrl (&ctrlbuf);
|
||||||
|
|
||||||
@ -2034,6 +2037,8 @@ check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce)
|
|||||||
static void *
|
static void *
|
||||||
start_connection_thread (void *arg)
|
start_connection_thread (void *arg)
|
||||||
{
|
{
|
||||||
|
static unsigned int last_session_id;
|
||||||
|
unsigned int session_id;
|
||||||
union int_and_ptr_u argval;
|
union int_and_ptr_u argval;
|
||||||
gnupg_fd_t fd;
|
gnupg_fd_t fd;
|
||||||
|
|
||||||
@ -2055,12 +2060,17 @@ start_connection_thread (void *arg)
|
|||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
log_info (_("handler for fd %d started\n"), FD2INT (fd));
|
log_info (_("handler for fd %d started\n"), FD2INT (fd));
|
||||||
|
|
||||||
start_command_handler (fd);
|
session_id = ++last_session_id;
|
||||||
|
if (!session_id)
|
||||||
|
session_id = ++last_session_id;
|
||||||
|
start_command_handler (fd, session_id);
|
||||||
|
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
log_info (_("handler for fd %d terminated\n"), FD2INT (fd));
|
log_info (_("handler for fd %d terminated\n"), FD2INT (fd));
|
||||||
active_connections--;
|
active_connections--;
|
||||||
|
|
||||||
|
workqueue_run_post_session_tasks (session_id);
|
||||||
|
|
||||||
#ifndef HAVE_W32_SYSTEM
|
#ifndef HAVE_W32_SYSTEM
|
||||||
argval.afd = ASSUAN_INVALID_FD;
|
argval.afd = ASSUAN_INVALID_FD;
|
||||||
npth_setspecific (my_tlskey_current_fd, argval.aptr);
|
npth_setspecific (my_tlskey_current_fd, argval.aptr);
|
||||||
|
@ -228,9 +228,11 @@ ksba_cert_t get_cert_local_ski (ctrl_t ctrl,
|
|||||||
gpg_error_t get_istrusted_from_client (ctrl_t ctrl, const char *hexfpr);
|
gpg_error_t get_istrusted_from_client (ctrl_t ctrl, const char *hexfpr);
|
||||||
int dirmngr_assuan_log_monitor (assuan_context_t ctx, unsigned int cat,
|
int dirmngr_assuan_log_monitor (assuan_context_t ctx, unsigned int cat,
|
||||||
const char *msg);
|
const char *msg);
|
||||||
void start_command_handler (gnupg_fd_t fd);
|
void start_command_handler (gnupg_fd_t fd, unsigned int session_id);
|
||||||
gpg_error_t dirmngr_status (ctrl_t ctrl, const char *keyword, ...);
|
gpg_error_t dirmngr_status (ctrl_t ctrl, const char *keyword, ...);
|
||||||
gpg_error_t dirmngr_status_help (ctrl_t ctrl, const char *text);
|
gpg_error_t dirmngr_status_help (ctrl_t ctrl, const char *text);
|
||||||
|
gpg_error_t dirmngr_status_helpf (ctrl_t ctrl, const char *format,
|
||||||
|
...) GPGRT_ATTR_PRINTF(2,3);
|
||||||
gpg_error_t dirmngr_status_printf (ctrl_t ctrl, const char *keyword,
|
gpg_error_t dirmngr_status_printf (ctrl_t ctrl, const char *keyword,
|
||||||
const char *format,
|
const char *format,
|
||||||
...) GPGRT_ATTR_PRINTF(3,4);
|
...) GPGRT_ATTR_PRINTF(3,4);
|
||||||
@ -258,6 +260,15 @@ void domaininfo_set_wkd_supported (const char *domain);
|
|||||||
void domaininfo_set_wkd_not_supported (const char *domain);
|
void domaininfo_set_wkd_not_supported (const char *domain);
|
||||||
void domaininfo_set_wkd_not_found (const char *domain);
|
void domaininfo_set_wkd_not_found (const char *domain);
|
||||||
|
|
||||||
|
/*-- workqueue.c --*/
|
||||||
|
typedef const char *(*wqtask_t)(ctrl_t ctrl, const char *args);
|
||||||
|
|
||||||
|
void workqueue_dump_queue (ctrl_t ctrl);
|
||||||
|
gpg_error_t workqueue_add_task (wqtask_t func, const char *args,
|
||||||
|
unsigned int session_id, int need_network);
|
||||||
|
void workqueue_run_global_tasks (ctrl_t ctrl, int with_network);
|
||||||
|
void workqueue_run_post_session_tasks (unsigned int session_id);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /*DIRMNGR_H*/
|
#endif /*DIRMNGR_H*/
|
||||||
|
@ -90,6 +90,9 @@ struct server_local_s
|
|||||||
/* Data used to associate an Assuan context with local server data */
|
/* Data used to associate an Assuan context with local server data */
|
||||||
assuan_context_t assuan_ctx;
|
assuan_context_t assuan_ctx;
|
||||||
|
|
||||||
|
/* The session id (a counter). */
|
||||||
|
unsigned int session_id;
|
||||||
|
|
||||||
/* Per-session LDAP servers. */
|
/* Per-session LDAP servers. */
|
||||||
ldap_server_t ldapservers;
|
ldap_server_t ldapservers;
|
||||||
|
|
||||||
@ -125,6 +128,9 @@ static es_cookie_io_functions_t data_line_cookie_functions =
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Local prototypes */
|
||||||
|
static const char *task_check_wkd_support (ctrl_t ctrl, const char *domain);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -992,8 +998,12 @@ cmd_wkd_get (assuan_context_t ctx, char *line)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GPG_ERR_NO_DATA:
|
case GPG_ERR_NO_DATA:
|
||||||
if (is_wkd_query) /* Mark that - we will latter do a check. */
|
if (is_wkd_query) /* Mark that and schedule a check. */
|
||||||
domaininfo_set_wkd_not_found (domain_orig);
|
{
|
||||||
|
domaininfo_set_wkd_not_found (domain_orig);
|
||||||
|
workqueue_add_task (task_check_wkd_support, domain_orig,
|
||||||
|
ctrl->server_local->session_id, 1);
|
||||||
|
}
|
||||||
else if (opt_policy_flags) /* No policy file - no support. */
|
else if (opt_policy_flags) /* No policy file - no support. */
|
||||||
domaininfo_set_wkd_not_supported (domain_orig);
|
domaininfo_set_wkd_not_supported (domain_orig);
|
||||||
break;
|
break;
|
||||||
@ -1014,6 +1024,20 @@ cmd_wkd_get (assuan_context_t ctx, char *line)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* A task to check whether DOMAIN supports WKD. This is done by
|
||||||
|
* checking whether the policy flags file can be read. */
|
||||||
|
static const char *
|
||||||
|
task_check_wkd_support (ctrl_t ctrl, const char *domain)
|
||||||
|
{
|
||||||
|
if (!ctrl || !domain)
|
||||||
|
return "check_wkd_support";
|
||||||
|
|
||||||
|
log_debug ("FIXME: Implement %s\n", __func__);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const char hlp_ldapserver[] =
|
static const char hlp_ldapserver[] =
|
||||||
"LDAPSERVER <data>\n"
|
"LDAPSERVER <data>\n"
|
||||||
@ -2428,12 +2452,15 @@ static const char hlp_getinfo[] =
|
|||||||
"pid - Return the process id of the server.\n"
|
"pid - Return the process id of the server.\n"
|
||||||
"tor - Return OK if running in Tor mode\n"
|
"tor - Return OK if running in Tor mode\n"
|
||||||
"dnsinfo - Return info about the DNS resolver\n"
|
"dnsinfo - Return info about the DNS resolver\n"
|
||||||
"socket_name - Return the name of the socket.\n";
|
"socket_name - Return the name of the socket.\n"
|
||||||
|
"session_id - Return the current session_id.\n"
|
||||||
|
"workqueue - Inspect the work queue\n";
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
cmd_getinfo (assuan_context_t ctx, char *line)
|
cmd_getinfo (assuan_context_t ctx, char *line)
|
||||||
{
|
{
|
||||||
ctrl_t ctrl = assuan_get_pointer (ctx);
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
|
char numbuf[50];
|
||||||
|
|
||||||
if (!strcmp (line, "version"))
|
if (!strcmp (line, "version"))
|
||||||
{
|
{
|
||||||
@ -2442,8 +2469,6 @@ cmd_getinfo (assuan_context_t ctx, char *line)
|
|||||||
}
|
}
|
||||||
else if (!strcmp (line, "pid"))
|
else if (!strcmp (line, "pid"))
|
||||||
{
|
{
|
||||||
char numbuf[50];
|
|
||||||
|
|
||||||
snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
|
snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
|
||||||
err = assuan_send_data (ctx, numbuf, strlen (numbuf));
|
err = assuan_send_data (ctx, numbuf, strlen (numbuf));
|
||||||
}
|
}
|
||||||
@ -2452,6 +2477,11 @@ cmd_getinfo (assuan_context_t ctx, char *line)
|
|||||||
const char *s = dirmngr_get_current_socket_name ();
|
const char *s = dirmngr_get_current_socket_name ();
|
||||||
err = assuan_send_data (ctx, s, strlen (s));
|
err = assuan_send_data (ctx, s, strlen (s));
|
||||||
}
|
}
|
||||||
|
else if (!strcmp (line, "session_id"))
|
||||||
|
{
|
||||||
|
snprintf (numbuf, sizeof numbuf, "%u", ctrl->server_local->session_id);
|
||||||
|
err = assuan_send_data (ctx, numbuf, strlen (numbuf));
|
||||||
|
}
|
||||||
else if (!strcmp (line, "tor"))
|
else if (!strcmp (line, "tor"))
|
||||||
{
|
{
|
||||||
int use_tor;
|
int use_tor;
|
||||||
@ -2487,6 +2517,11 @@ cmd_getinfo (assuan_context_t ctx, char *line)
|
|||||||
}
|
}
|
||||||
err = 0;
|
err = 0;
|
||||||
}
|
}
|
||||||
|
else if (!strcmp (line, "workqueue"))
|
||||||
|
{
|
||||||
|
workqueue_dump_queue (ctrl);
|
||||||
|
err = 0;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
|
err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
|
||||||
|
|
||||||
@ -2614,9 +2649,10 @@ dirmngr_assuan_log_monitor (assuan_context_t ctx, unsigned int cat,
|
|||||||
|
|
||||||
|
|
||||||
/* Startup the server and run the main command loop. With FD = -1,
|
/* Startup the server and run the main command loop. With FD = -1,
|
||||||
use stdin/stdout. */
|
* use stdin/stdout. SESSION_ID is either 0 or a unique number
|
||||||
|
* identifying a session. */
|
||||||
void
|
void
|
||||||
start_command_handler (assuan_fd_t fd)
|
start_command_handler (assuan_fd_t fd, unsigned int session_id)
|
||||||
{
|
{
|
||||||
static const char hello[] = "Dirmngr " VERSION " at your service";
|
static const char hello[] = "Dirmngr " VERSION " at your service";
|
||||||
static char *hello_line;
|
static char *hello_line;
|
||||||
@ -2693,6 +2729,8 @@ start_command_handler (assuan_fd_t fd)
|
|||||||
assuan_register_option_handler (ctx, option_handler);
|
assuan_register_option_handler (ctx, option_handler);
|
||||||
assuan_register_reset_notify (ctx, reset_notify);
|
assuan_register_reset_notify (ctx, reset_notify);
|
||||||
|
|
||||||
|
ctrl->server_local->session_id = session_id;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
rc = assuan_accept (ctx);
|
rc = assuan_accept (ctx);
|
||||||
@ -2792,8 +2830,7 @@ dirmngr_status (ctrl_t ctrl, const char *keyword, ...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Print a help status line. TEXTLEN gives the length of the text
|
/* Print a help status line. The function splits text at LFs. */
|
||||||
from TEXT to be printed. The function splits text at LFs. */
|
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
dirmngr_status_help (ctrl_t ctrl, const char *text)
|
dirmngr_status_help (ctrl_t ctrl, const char *text)
|
||||||
{
|
{
|
||||||
@ -2823,6 +2860,26 @@ dirmngr_status_help (ctrl_t ctrl, const char *text)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Print a help status line using a printf like format. The function
|
||||||
|
* splits text at LFs. */
|
||||||
|
gpg_error_t
|
||||||
|
dirmngr_status_helpf (ctrl_t ctrl, const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list arg_ptr;
|
||||||
|
gpg_error_t err;
|
||||||
|
char *buf;
|
||||||
|
|
||||||
|
va_start (arg_ptr, format);
|
||||||
|
buf = es_vbsprintf (format, arg_ptr);
|
||||||
|
err = buf? 0 : gpg_error_from_syserror ();
|
||||||
|
va_end (arg_ptr);
|
||||||
|
if (!err)
|
||||||
|
err = dirmngr_status_help (ctrl, buf);
|
||||||
|
es_free (buf);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This function is similar to print_assuan_status but takes a CTRL
|
/* This function is similar to print_assuan_status but takes a CTRL
|
||||||
* arg instead of an assuan context as first argument. */
|
* arg instead of an assuan context as first argument. */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
|
214
dirmngr/workqueue.c
Normal file
214
dirmngr/workqueue.c
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
/* workqueue.c - Maintain a queue of background tasks
|
||||||
|
* Copyright (C) 2017 Werner Koch
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "dirmngr.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* An object for one item in the workqueue. */
|
||||||
|
struct wqitem_s
|
||||||
|
{
|
||||||
|
struct wqitem_s *next;
|
||||||
|
|
||||||
|
/* This flag is set if the task requires network access. */
|
||||||
|
unsigned int need_network:1;
|
||||||
|
|
||||||
|
/* The id of the session which created this task. If this is 0 the
|
||||||
|
* task is not associated with a specific session. */
|
||||||
|
unsigned int session_id;
|
||||||
|
|
||||||
|
/* The function to perform the backgrount task. */
|
||||||
|
wqtask_t func;
|
||||||
|
|
||||||
|
/* A string with the string argument for that task. */
|
||||||
|
char args[1];
|
||||||
|
};
|
||||||
|
typedef struct wqitem_s *wqitem_t;
|
||||||
|
|
||||||
|
|
||||||
|
/* The workque is a simple linked list. */
|
||||||
|
static wqitem_t workqueue;
|
||||||
|
|
||||||
|
|
||||||
|
/* Dump the queue using Assuan status comments. */
|
||||||
|
void
|
||||||
|
workqueue_dump_queue (ctrl_t ctrl)
|
||||||
|
{
|
||||||
|
wqitem_t saved_workqueue;
|
||||||
|
wqitem_t item;
|
||||||
|
unsigned int count;
|
||||||
|
|
||||||
|
/* Temporay detach the entiere workqueue so that other threads don't
|
||||||
|
* get into our way. */
|
||||||
|
saved_workqueue = workqueue;
|
||||||
|
workqueue = NULL;
|
||||||
|
|
||||||
|
for (count=0, item = saved_workqueue; item; item = item->next)
|
||||||
|
count++;
|
||||||
|
|
||||||
|
dirmngr_status_helpf (ctrl, "wq: number of entries: %u", count);
|
||||||
|
for (item = saved_workqueue; item; item = item->next)
|
||||||
|
dirmngr_status_helpf (ctrl, "wq: sess=%u net=%d %s(\"%.100s%s\")",
|
||||||
|
item->session_id, item->need_network,
|
||||||
|
item->func? item->func (NULL, NULL): "nop",
|
||||||
|
item->args, strlen (item->args) > 100? "[...]":"");
|
||||||
|
|
||||||
|
/* Restore then workqueue. Actually we append the saved queue do a
|
||||||
|
* possibly updated workqueue. */
|
||||||
|
if (!(item=workqueue))
|
||||||
|
workqueue = saved_workqueue;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (item->next)
|
||||||
|
item = item->next;
|
||||||
|
item->next = saved_workqueue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Append the task (FUNC,ARGS) to the work queue. FUNC shall return
|
||||||
|
* its name when called with (NULL, NULL). */
|
||||||
|
gpg_error_t
|
||||||
|
workqueue_add_task (wqtask_t func, const char *args, unsigned int session_id,
|
||||||
|
int need_network)
|
||||||
|
{
|
||||||
|
wqitem_t item, wi;
|
||||||
|
|
||||||
|
item = xtrycalloc (1, sizeof *item + strlen (args));
|
||||||
|
if (!item)
|
||||||
|
return gpg_error_from_syserror ();
|
||||||
|
strcpy (item->args, args);
|
||||||
|
item->func = func;
|
||||||
|
item->session_id = session_id;
|
||||||
|
item->need_network = !!need_network;
|
||||||
|
|
||||||
|
if (!(wi=workqueue))
|
||||||
|
workqueue = item;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (wi->next)
|
||||||
|
wi = wi->next;
|
||||||
|
wi->next = item;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Run the task described by ITEM. ITEM must have been detached from
|
||||||
|
* the workqueue; its ownership is transferred to this fucntion. */
|
||||||
|
static void
|
||||||
|
run_a_task (ctrl_t ctrl, wqitem_t item)
|
||||||
|
{
|
||||||
|
log_assert (!item->next);
|
||||||
|
|
||||||
|
if (opt.verbose)
|
||||||
|
log_info ("session %u: running %s(\"%s%s\")\n",
|
||||||
|
item->session_id,
|
||||||
|
item->func? item->func (NULL, NULL): "nop",
|
||||||
|
item->args, strlen (item->args) > 100? "[...]":"");
|
||||||
|
if (item->func)
|
||||||
|
item->func (ctrl, item->args);
|
||||||
|
|
||||||
|
xfree (item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Run tasks not associated with a session. This is called from the
|
||||||
|
* ticker every few minutes. If WITH_NETWORK is not set tasks which
|
||||||
|
* require the network are not run. */
|
||||||
|
void
|
||||||
|
workqueue_run_global_tasks (ctrl_t ctrl, int with_network)
|
||||||
|
{
|
||||||
|
wqitem_t item, prev;
|
||||||
|
|
||||||
|
with_network = !!with_network;
|
||||||
|
|
||||||
|
if (opt.verbose)
|
||||||
|
log_info ("running scheduled tasks%s\n", with_network?" (with network)":"");
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
prev = NULL;
|
||||||
|
for (item = workqueue; item; prev = item, item = item->next)
|
||||||
|
if (!item->session_id
|
||||||
|
&& (!item->need_network || (item->need_network && with_network)))
|
||||||
|
break;
|
||||||
|
if (!item)
|
||||||
|
break; /* No more tasks to run. */
|
||||||
|
|
||||||
|
/* Detach that item from the workqueue. */
|
||||||
|
if (!prev)
|
||||||
|
workqueue = item->next;
|
||||||
|
else
|
||||||
|
prev->next = item->next;
|
||||||
|
item->next = NULL;
|
||||||
|
|
||||||
|
/* Run the task. */
|
||||||
|
run_a_task (ctrl, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Run tasks scheduled for running after a session. Those tasks are
|
||||||
|
* identified by the SESSION_ID. */
|
||||||
|
void
|
||||||
|
workqueue_run_post_session_tasks (unsigned int session_id)
|
||||||
|
{
|
||||||
|
struct server_control_s ctrlbuf;
|
||||||
|
ctrl_t ctrl = NULL;
|
||||||
|
wqitem_t item, prev;
|
||||||
|
|
||||||
|
if (!session_id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
prev = NULL;
|
||||||
|
for (item = workqueue; item; prev = item, item = item->next)
|
||||||
|
if (item->session_id == session_id)
|
||||||
|
break;
|
||||||
|
if (!item)
|
||||||
|
break; /* No more tasks for this session. */
|
||||||
|
|
||||||
|
/* Detach that item from the workqueue. */
|
||||||
|
if (!prev)
|
||||||
|
workqueue = item->next;
|
||||||
|
else
|
||||||
|
prev->next = item->next;
|
||||||
|
item->next = NULL;
|
||||||
|
|
||||||
|
/* Create a CTRL object the first time we need it. */
|
||||||
|
if (!ctrl)
|
||||||
|
{
|
||||||
|
memset (&ctrlbuf, 0, sizeof ctrlbuf);
|
||||||
|
ctrl = &ctrlbuf;
|
||||||
|
dirmngr_init_default_ctrl (ctrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Run the task. */
|
||||||
|
run_a_task (ctrl, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
dirmngr_deinit_default_ctrl (ctrl);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user