aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2020-04-16 19:54:23 +0300
committerSergey Poznyakoff <gray@gnu.org>2020-04-16 20:03:29 +0300
commita6cc8f5fcbcbf4c707149940de2ee9a33220c34d (patch)
tree3b0da6ae669a58779c9f40503191e6808a60e1b9
parent2cc5b63b5f90d2dd9b05f50ac28e379d417f1a8c (diff)
downloadwydawca-a6cc8f5fcbcbf4c707149940de2ee9a33220c34d.tar.gz
wydawca-a6cc8f5fcbcbf4c707149940de2ee9a33220c34d.tar.bz2
Rewrite as a multi-threaded program.
* NEWS: Update. * configure.ac: Version 3.1.95 * src/Makefile.am (wydawca_SOURCES): Remove job.c (LDADD): Link with libpthread. * src/job.c: Remove. * src/config.c: Remove the wakeup-interval statement. * src/net.c (wydawca_listener): Rewrite as a thread function wy_thr_listen. * src/timer.c (timer_get): Use thread-specific storage. (timer_get_count): Remove. * src/triplet.c: Rewrite using multi-thread model. * src/wydawca.c: Likewise. * src/wydawca.h: Update. * tests/check-fail.at: Update expected output. * tests/check-notify.at: Likewise. * tests/inotify-ok.at: Likewise. * tests/inotify-rmsymlink.at: Likewise. * tests/inotify-symlink.at: Likewise. * tests/inotify-unatt00.at: Likewise. * tests/inotify-unatt01.at: Likewise. * tests/upl12f.at: Likewise. * tests/upload-dry.at: Likewise. `
-rw-r--r--NEWS4
-rw-r--r--configure.ac2
-rw-r--r--doc/wydawca.texi14
-rw-r--r--src/Makefile.am3
-rw-r--r--src/config.c3
-rw-r--r--src/job.c441
-rw-r--r--src/net.c43
-rw-r--r--src/timer.c43
-rw-r--r--src/triplet.c393
-rw-r--r--src/wydawca.c108
-rw-r--r--src/wydawca.h63
-rw-r--r--tests/check-fail.at6
-rw-r--r--tests/check-notify.at6
-rw-r--r--tests/inotify-ok.at1
-rw-r--r--tests/inotify-rmsymlink.at1
-rw-r--r--tests/inotify-symlink.at1
-rw-r--r--tests/inotify-unatt00.at1
-rw-r--r--tests/inotify-unatt01.at1
-rw-r--r--tests/upl12f.at6
-rw-r--r--tests/upload-dry.at3
20 files changed, 416 insertions, 727 deletions
diff --git a/NEWS b/NEWS
index 9324194..2789798 100644
--- a/NEWS
+++ b/NEWS
@@ -1,9 +1,9 @@
-Wydawca NEWS -- history of user-visible changes. 2020-04-09
+Wydawca NEWS -- history of user-visible changes. 2020-04-16
See the end of file for copying conditions.
Please send Wydawca bug reports to <bug-wydawca@gnu.org.ua>.
-Version 3.1.90 (git)
+Version 3.1.95 (git)
* Configuration file name changed to "wydawca.conf"
diff --git a/configure.ac b/configure.ac
index 26ae9ac..f99f49f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -15,7 +15,7 @@
# along with wydawca. If not, see <http://www.gnu.org/licenses/>.
AC_PREREQ(2.63)
-AC_INIT([wydawca], 3.1.90, [bug-wydawca@gnu.org.ua], [wydawca],
+AC_INIT([wydawca], 3.1.95, [bug-wydawca@gnu.org.ua], [wydawca],
[http://www.gnu.org.ua/software/wydawca])
AC_CONFIG_SRCDIR([src/wydawca.c])
AC_CONFIG_AUX_DIR([build-aux])
diff --git a/doc/wydawca.texi b/doc/wydawca.texi
index e4365ec..430e300 100644
--- a/doc/wydawca.texi
+++ b/doc/wydawca.texi
@@ -1129,16 +1129,6 @@ Declare a special service name, which will be treated as a request to
process all spools.
@end deffn
-@deffn {Config} wakeup-interval time
-Specifies the wake-up interval for the daemon. If no connections
-are requested during @var{time}, the server will wake up
-and sweep all the configured spools. It is useful for periodical
-removal of expired triplets. See also @code{file-sweep-time}
-statement (@pxref{general, file-sweep-time}).
-
-@xref{time interval specification}, for the syntax of @var{time}.
-@end deffn
-
@deffn {Config} pidfile file
Store master process @acronym{PID} in @var{file}. Default pidfile
location is @file{@var{localstatedir}/run/wydawca.pid}.
@@ -3361,10 +3351,6 @@ foreground @var{arg:@i{boolean}};
# @xref{general, single-process}.
single-process @var{arg:@i{boolean}};
-# @r{Set wake-up interval.}
-# @xref{general, wakeup-interval}.
-wakeup-interval @var{time:@i{string}};
-
# @r{Set pid file name.}
# @xref{general, pidfile}.
pidfile @var{file:@i{string}};
diff --git a/src/Makefile.am b/src/Makefile.am
index 6e67c9c..9d9d4d9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -33,7 +33,6 @@ wydawca_SOURCES=\
event.c\
gpg.c\
interval.c\
- job.c\
lock.c\
module.c\
net.c\
@@ -61,7 +60,7 @@ SUFFIXES=.opt .c .h
.opt.h:
$(AM_V_GEN)m4 -s $(top_srcdir)/@GRECS_SUBDIR@/build-aux/getopt.m4 $< > $@
-LDADD=@GRECS_LDADD@ @SQLLIB@ @GPGMELIB@ @LIBLTDL@
+LDADD=@GRECS_LDADD@ @SQLLIB@ @GPGMELIB@ @LIBLTDL@ -lpthread
AM_CPPFLAGS= \
-I$(top_srcdir)/include\
@GRECS_INCLUDES@ @MAILUTILS_INCLUDES@\
diff --git a/src/config.c b/src/config.c
index c928431..7d0e760 100644
--- a/src/config.c
+++ b/src/config.c
@@ -1440,9 +1440,6 @@ static struct grecs_keyword wydawca_kw[] = {
{ "single-process", NULL,
N_("Do not spawn subprocesses"),
grecs_type_bool, GRECS_DFLT, &single_process },
- { "wakeup-interval", N_("time"),
- N_("Set wake-up interval"),
- grecs_type_string, GRECS_CONST, &wakeup_interval, 0, cb_interval },
{ "pidfile", N_("file"),
N_("Set pid file name"),
grecs_type_string, GRECS_CONST, &pidfile},
diff --git a/src/job.c b/src/job.c
deleted file mode 100644
index 84d3bb5..0000000
--- a/src/job.c
+++ /dev/null
@@ -1,441 +0,0 @@
-/* wydawca - automatic release submission daemon
- Copyright (C) 2009-2013, 2017, 2019-2020 Sergey Poznyakoff
-
- This program 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.
-
- This program 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 <http://www.gnu.org/licenses/>. */
-
-#include "wydawca.h"
-
-enum {
- STATE_FINISHED,
- STATE_QUEUED,
- STATE_ACTIVE
-};
-
-#define STATE_MASK(s) (1<<(s))
-
-#define STATE_ANY \
- (STATE_MASK(STATE_FINISHED) |\
- STATE_MASK(STATE_QUEUED) | \
- STATE_MASK(STATE_ACTIVE))
-
-struct job {
- enum job_type type;
- struct job *next, *prev;
- int state;
- pid_t pid;
- time_t timestamp;
- int exit_status;
- char *printable;
- union {
- struct wy_triplet *triplet; /* JOB_TRIPLET */
- struct spool *spool; /* JOB_SPOOL */
- } v;
-};
-
-struct job *queue;
-size_t jobmax;
-size_t jobcnt;
-
-static int wakeup;
-
-RETSIGTYPE
-queue_signal(int sig)
-{
- wakeup = 1;
- signal(sig, queue_signal);
-}
-
-void
-set_timer(time_t interval)
-{
- wakeup = 0;
- if (interval)
- alarm(interval);
-}
-
-
-char const *
-job_printable(struct job *job)
-{
- if (!job->printable) {
- size_t s = 0;
-
- switch (job->type) {
- case JOB_TRIPLET:
- if (grecs_asprintf(&job->printable, &s,
- "triplet(%s,%s)",
- job->v.triplet->spool->tag,
- job->v.triplet->name))
- grecs_alloc_die();
- break;
-
- case JOB_SPOOL:
- if (grecs_asprintf(&job->printable, &s,
- "spool(%s)",
- job->v.spool->tag))
- grecs_alloc_die();
- break;
-
- case JOB_ALL_SPOOLS:
- job->printable = grecs_strdup("all spools");
- }
- }
- return job->printable;
-}
-
-struct job *
-job_locate(int type, int mask, void *data)
-{
- struct job *p;
- for (p = queue; p; p = p->next)
- if (p->type == type && (STATE_MASK(p->state) & mask)) {
- switch (p->type) {
- case JOB_TRIPLET:
- if (p->v.triplet == data)
- return p;
- break;
-
- case JOB_SPOOL:
- if (p->v.spool == data)
- return p;
- break;
-
- case JOB_ALL_SPOOLS:
- return p;
- }
- }
- return p;
-}
-
-size_t
-job_active_count()
-{
- struct job *job;
- size_t count = 0;
- for (job = queue; job; job = job->next)
- if (job->state == STATE_ACTIVE)
- count++;
- return count;
-}
-
-int
-wydawca_scanner(struct job *job)
-{
- int rc;
- initstats();
- timer_start("wydawca");
- spool_create_timers();
- switch (job->type) {
- case JOB_TRIPLET:
- triplet_commit(job->v.triplet);
- rc = 0;
- break;
-
- case JOB_ALL_SPOOLS:
- rc = scan_all_spools();
- break;
-
- case JOB_SPOOL:
- rc = scan_spool(job->v.spool);
- notify_flush(job->v.spool);
- }
- timer_stop("wydawca");
- if (!single_process)
- logstats();
- return rc;
-}
-
-int
-job_start(struct job *job)
-{
- pid_t pid;
-
- if (jobmax && jobcnt == jobmax) {
- wy_log(LOG_NOTICE, "maximum number of processes active");
- return 1;
- }
-
- wy_debug(1, (_("starting job: %s"), job_printable(job)));
-
- if (single_process) {
- if (wydawca_scanner(job))
- job->state = STATE_QUEUED;
- else
- job->state = STATE_FINISHED;
- wakeup = 1;
- return 0;
- }
-
- pid = fork();
- if (pid == 0) {
- signal(SIGHUP, SIG_DFL);
- signal(SIGTERM, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
- signal(SIGINT, SIG_DFL);
- signal(SIGCHLD, SIG_DFL);
- signal(SIGALRM, SIG_DFL);
- alarm(0);
- exit(wydawca_scanner(job) ? WYDAWCA_EX_AGAIN : 0);
- } else if (pid == -1) {
- wy_log(LOG_CRIT, "fork: %s", strerror(errno));
- return -1;
- } else {
- job->state = STATE_ACTIVE;
- job->pid = pid;
- jobcnt++;
- }
- return 0;
-}
-
-void
-job_remove(struct job *job)
-{
- struct job *p;
-
- wy_debug(1, (_("removing job: %s"), job_printable(job)));
- p = job->prev;
- if (p)
- p->next = job->next;
- else
- queue = job->next;
-
- p = job->next;
- if (p)
- p->prev = job->prev;
-}
-
-void
-job_destroy(struct job *job)
-{
- free(job->printable);
- free(job);
-}
-
-void
-job_insert(struct job *job, struct job *elt)
-{
- struct job *p;
-
- job->prev = elt;
- if (!elt) {
- if (queue)
- queue->prev = job;
- job->next = queue;
- queue = job;
- return;
- }
-
- p = elt->next;
- elt->next = job;
-
- if (p)
- p->prev = job;
-}
-
-void
-job_schedule(int type, void *data)
-{
- struct job *job;
-
- job = job_locate(type,
- type == JOB_TRIPLET
- ? STATE_MASK(STATE_QUEUED) : STATE_ANY,
- data);
- if (!job) {
- job = grecs_zalloc(sizeof(*job));
- job->type = type;
- job->pid = -1;
- time(&job->timestamp);
-
- switch (type) {
- case JOB_TRIPLET:{
- struct wy_triplet *tp = data;
- job->v.triplet = tp;
- tp->job = job;
- break;
- }
-
- case JOB_SPOOL:
- job->v.spool = data;
- break;
-
- case JOB_ALL_SPOOLS:
- break;
- }
- wy_debug(1, (_("scheduling job %s"), job_printable(job)));
- job_insert(job, NULL);
- }
-
- job->state = STATE_QUEUED;
- job_start(job);
-}
-
-static void
-print_status(struct job *job, int expect_term)
-{
- int status = job->exit_status;
-
- if (WIFEXITED(status)) {
- int exit_code = WEXITSTATUS(status);
- if (exit_code == 0) {
- wy_debug(1, (_("%lu (job %s) exited successfully"),
- (unsigned long) job->pid, job_printable(job)));
- } else if (exit_code == WYDAWCA_EX_AGAIN) {
- wy_debug(1, (_("%lu (job %s) reported tempfail"),
- (unsigned long) job->pid, job_printable(job)));
- } else
- wy_log(LOG_ERR,
- _("%lu (job %s) failed with status %d"),
- (unsigned long) job->pid,
- job_printable(job), exit_code);
- } else if (WIFSIGNALED(status)) {
- int prio;
- if (expect_term && WTERMSIG(status) == SIGTERM) {
- if (!wy_debug_level)
- return;
- prio = LOG_DEBUG;
- } else
- prio = LOG_ERR;
-
- wy_log(prio,
- _("%lu (job %s) terminated on signal %d"),
- (unsigned long) job->pid, job_printable(job),
- WTERMSIG(status));
- } else if (WIFSTOPPED(status))
- wy_log(LOG_NOTICE,
- _("%lu (job %s) stopped on signal %d"),
- (unsigned long) job->pid, job_printable(job),
- WSTOPSIG(status));
-#ifdef WCOREDUMP
- else if (WCOREDUMP(status))
- wy_log(LOG_NOTICE,
- _("%lu (job %s) dumped core"),
- (unsigned long) job->pid, job_printable(job));
-#endif
- else
- wy_log(LOG_ERR,
- _("%lu (job %s) terminated with unrecognized status"),
- (unsigned long) job->pid, job_printable(job));
-}
-
-void
-job_queue_runner(time_t min_interval)
-{
- struct job *job;
- time_t now = time(NULL);
-
- if (wakeup) {
- wakeup = 0;
-
- for (;;) {
- int status;
-
- pid_t pid = waitpid((pid_t) - 1, &status, WNOHANG);
- if (pid <= 0)
- break;
- for (job = queue; job; job = job->next) {
- if (job->state == STATE_ACTIVE && job->pid == pid) {
- remove_triplet(job->v.triplet, 1);
- job->v.triplet = NULL;
- job->exit_status = status;
- job->state = STATE_FINISHED;
- jobcnt--;
- }
- }
- }
-
- for (job = queue; job;) {
- struct job *next = job->next;
- if (job->state == STATE_FINISHED) {
- print_status(job, 0);
- if (WIFEXITED(job->exit_status) &&
- WEXITSTATUS(job->exit_status) == WYDAWCA_EX_AGAIN) {
- time_t interval = lock_timeout;
- if (interval == 0)
- interval = lock_expire_time;
- /* Re-queue the job */
- job->state = STATE_QUEUED;
- job->timestamp = now + interval;
- } else {
- job_remove(job);
- job_destroy(job);
- job = next;
- continue;
- }
- }
-
- if (job->state == STATE_QUEUED) {
- if (job->timestamp >= now) {
- if (job_start(job))
- pause();
- now = time(NULL);
- } else {
- time_t interval = job->timestamp - now;
- if (min_interval == 0 || interval < min_interval)
- min_interval = interval;
- }
- }
-
- job = next;
- }
- }
-
- if (min_interval) {
- wy_debug(2, (_("computed interval: %lu"), min_interval));
- set_timer(min_interval);
- }
-}
-
-void
-job_queue_wait(void)
-{
- while (queue) {
- int status;
- struct job *job;
-
- pid_t pid = waitpid((pid_t) - 1, &status, 0);
- if (pid <= 0)
- break;
- for (job = queue; job; job = job->next) {
- if (job->state == STATE_ACTIVE && job->pid == pid) {
- remove_triplet(job->v.triplet, 1);
- job->v.triplet = NULL;
- job->exit_status = status;
- job->state = STATE_FINISHED;
- jobcnt--;
- }
- }
-
- for (job = queue; job;) {
- struct job *next = job->next;
- if (job->state == STATE_FINISHED) {
- print_status(job, 0);
- job_remove(job);
- job_destroy(job);
- } else if (job->state == STATE_QUEUED) {
- job_remove(job);
- job_destroy(job);
- }
- job = next;
- }
- }
- logstats();
-}
-
-void
-job_init(void)
-{
- signal(SIGCHLD, queue_signal);
- signal(SIGALRM, queue_signal);
-}
diff --git a/src/net.c b/src/net.c
index 4a0900e..3f8d291 100644
--- a/src/net.c
+++ b/src/net.c
@@ -129,28 +129,12 @@ handle_connection(FILE * in, FILE * out)
}
if (spool)
- job_schedule_spool(spool);
+ scan_spool(spool);
else
- job_schedule_all();
+ scan_all_spools();
free(buf);
}
-int reconfigure;
-static int terminate;
-
-RETSIGTYPE
-sig_hup(int sig)
-{
- reconfigure = 1;
- terminate = 1;
-}
-
-RETSIGTYPE
-sig_term(int sig)
-{
- terminate = 1;
-}
-
static inline int
notify_parent(void)
{
@@ -158,8 +142,8 @@ notify_parent(void)
return (p && strcmp(p, "1") == 0);
}
-void
-wydawca_listener(void)
+void *
+wy_thr_listen(void *ptr)
{
int ctlfd = open_listener();
int wfd = watcher_init();
@@ -181,16 +165,9 @@ wydawca_listener(void)
if (notify_parent())
kill(getppid(), SIGUSR1);
- signal(SIGHUP, sig_hup);
- signal(SIGTERM, sig_term);
- signal(SIGQUIT, sig_term);
- signal(SIGINT, sig_term);
- while (!terminate) {
+ while (1) {
int rc;
fd_set rset;
- struct timeval to, *pto;
-
- job_queue_runner(triplet_sweep());
FD_ZERO(&rset);
if (ctlfd != -1)
@@ -198,14 +175,7 @@ wydawca_listener(void)
if (wfd != -1)
FD_SET(wfd, &rset);
- if (wakeup_interval) {
- to.tv_sec = wakeup_interval;
- to.tv_usec = 0;
- *pto = to;
- } else
- pto = NULL;
-
- rc = select(maxfd + 1, &rset, NULL, NULL, pto);
+ rc = select(maxfd + 1, &rset, NULL, NULL, NULL);
if (rc == 0)
continue;
else if (rc < 0) {
@@ -250,4 +220,5 @@ wydawca_listener(void)
fclose(out);
}
}
+ return NULL;
}
diff --git a/src/timer.c b/src/timer.c
index 162ae7d..f5d7c93 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -33,9 +33,6 @@ struct timer_slot {
struct rusage children_mark;
};
-static struct grecs_symtab *timer_table;
-static size_t _timer_count;
-
static unsigned
hash_string_ci(const char *string, unsigned long n_buckets)
{
@@ -54,28 +51,43 @@ timer_hasher(void *ptr, unsigned long n_buckets)
return hash_string_ci(tp->name, n_buckets);
}
+static pthread_key_t key;
+static pthread_once_t key_once = PTHREAD_ONCE_INIT;
+
+static void
+timer_free(void *f)
+{
+ grecs_symtab_free(f);
+}
+
+static void
+make_key(void)
+{
+ pthread_key_create(&key, timer_free);
+}
+
/* Lookup a timer by its name. If it does not exist, create it. */
wydawca_timer_t
timer_get(const char *name)
{
- struct timer_slot key, *ret;
+ struct timer_slot slot, *ret;
int install = 1;
-
- key.name = (char *) name;
-
- if (!timer_table) {
- timer_table = grecs_symtab_create(sizeof(key),
+ struct grecs_symtab *timer_table;
+
+ pthread_once(&key_once, make_key);
+ if ((timer_table = pthread_getspecific(key)) == NULL) {
+ timer_table = grecs_symtab_create(sizeof(slot),
timer_hasher,
NULL, NULL, NULL, NULL);
if (!timer_table)
grecs_alloc_die();
+ pthread_setspecific(key, timer_table);
}
-
- ret = grecs_symtab_lookup_or_install(timer_table, &key, &install);
+
+ slot.name = (char *)name;
+ ret = grecs_symtab_lookup_or_install(timer_table, &slot, &install);
if (!ret)
grecs_alloc_die();
- if (install)
- _timer_count++;
return ret;
}
@@ -182,8 +194,3 @@ timer_format_time(double t)
return str;
}
-size_t
-timer_get_count()
-{
- return _timer_count;
-}
diff --git a/src/triplet.c b/src/triplet.c
index e41da07..797a09e 100644
--- a/src/triplet.c
+++ b/src/triplet.c
@@ -19,14 +19,106 @@
/* Triplets are stored in a symtab: */
static struct grecs_symtab *triplet_table;
+static pthread_mutex_t triplet_table_mutex = PTHREAD_MUTEX_INITIALIZER;
+
/* ... and are organized into a doubly-linked list, using the prev and
- next members of struct wy_triplet. The list is ordered so that
+ next members of struct wy_triplet: */
+struct triplet_list {
+ struct wy_triplet *head, *tail;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+};
+
+#define TRIPLET_LIST_INITIALIZER \
+ { NULL, NULL, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER }
+
+/* Two such lists are maintained. The pending list is ordered so that
prev points to a triplet older than this one, and next points to a
- newer triplet. The triplet_list variable points to the root of the
- list, i.e. the oldest triplet available. */
-static struct wy_triplet *triplet_list;
+ newer triplet. Its head member points to the oldest triplet available. */
+static struct triplet_list triplet_pending_list = TRIPLET_LIST_INITIALIZER;
+
+/* The running list contains triplets which are processed by running
+ threads */
+static struct triplet_list triplet_running_list = TRIPLET_LIST_INITIALIZER;
/* Functions for building the ordered doubly-linked list of triplets */
+
+static inline void
+triplet_list_lock(struct triplet_list *list)
+{
+ pthread_mutex_lock(&list->mutex);
+}
+
+static inline void
+triplet_list_unlock(struct triplet_list *list)
+{
+ pthread_mutex_unlock(&list->mutex);
+}
+
+void
+triplet_list_unlink(struct triplet_list *list, struct wy_triplet *tp)
+{
+ int head_changed = 0;
+
+ if (tp->prev)
+ tp->prev->next = tp->next;
+ else if (tp == list->head) {
+ list->head = tp->next;
+ head_changed = 1;
+ }
+
+ if (tp->next)
+ tp->next->prev = tp->prev;
+ else
+ list->tail = tp->prev;
+
+ tp->next = tp->prev = NULL;
+ if (head_changed)
+ pthread_cond_broadcast(&list->cond);
+ tp->list = NULL;
+}
+
+static void
+triplet_list_insert(struct triplet_list *list,
+ struct wy_triplet *newp, struct wy_triplet *anchor,
+ int after)
+{
+ int head_changed = 0;
+
+ if (!anchor) {
+ newp->prev = NULL;
+ newp->next = list->head;
+ if (list->head)
+ list->head->prev = newp;
+ else
+ list->tail = newp;
+ list->head = newp;
+ head_changed = 1;
+ } else if (after) {
+ if (anchor->next)
+ anchor->next->prev = newp;
+ else
+ list->tail = newp;
+ newp->prev = anchor;
+ newp->next = anchor->next;
+ anchor->next = newp;
+ } else {
+ if (anchor->prev)
+ anchor->prev->next = newp;
+ else {
+ list->head = newp;
+ head_changed = 1;
+ }
+ newp->prev = anchor->prev;
+ newp->next = anchor;
+ anchor->prev = newp;
+ }
+ newp->list = list;
+ if (head_changed)
+ pthread_cond_broadcast(&list->cond);
+}
+
+
static time_t
triplet_timestamp(struct wy_triplet *tp)
{
@@ -43,69 +135,35 @@ triplet_timestamp(struct wy_triplet *tp)
return t;
}
-static time_t
-triplet_ttl(struct wy_triplet *tp)
+static struct timespec *
+triplet_ttl(struct wy_triplet *tp, struct timespec *ts)
{
time_t t;
if (!tp)
- return 0;
+ return NULL;
t = time(NULL) - triplet_timestamp(tp);
if (t < tp->spool->file_sweep_time)
- return tp->spool->file_sweep_time - t;
- return 0;
-}
-
-void
-triplet_list_unlink(struct wy_triplet *tp)
-{
- if (tp->prev)
- tp->prev->next = tp->next;
- else if (tp == triplet_list)
- triplet_list = tp->next;
-
- if (tp->next)
- tp->next->prev = tp->prev;
-
- tp->next = tp->prev = NULL;
-}
-
-static void
-triplet_list_insert_before(struct wy_triplet *newp, struct wy_triplet *anchor)
-{
- if (!anchor) {
- triplet_list = newp;
- return;
- }
-
- if (anchor->prev)
- anchor->prev->next = newp;
+ ts->tv_sec += tp->spool->file_sweep_time - t;
else
- triplet_list = newp;
- newp->prev = anchor->prev;
-
- anchor->prev = newp;
- newp->next = anchor;
+ ts->tv_sec = 0;
+ ts->tv_nsec = 0;
+ return ts;
}
+
void
-triplet_list_ordered_insert(struct wy_triplet *tp)
+triplet_list_ordered_insert(struct triplet_list *list, struct wy_triplet *tp)
{
time_t t = triplet_timestamp(tp);
struct wy_triplet *p, *prev = NULL;
- for (p = triplet_list; p && triplet_timestamp(p) < t;
+ for (p = list->head; p && triplet_timestamp(p) < t;
prev = p, p = p->next);
if (p)
- triplet_list_insert_before(tp, p);
- else if (prev) {
- prev->next = tp;
- tp->prev = prev;
- tp->next = NULL;
- } else {
- tp->next = tp->prev = NULL;
- triplet_list = tp;
- }
+ triplet_list_insert(list, tp, p, 0);
+ else
+ triplet_list_insert(list, tp, prev ? prev->next : NULL, 1);
}
static struct wy_user *
@@ -190,6 +248,7 @@ register_file(struct file_info *finfo, struct spool *spool)
struct wy_triplet key, *ret;
int install = 1;
+ pthread_mutex_lock(&triplet_table_mutex);
if (!triplet_table) {
triplet_table =
grecs_symtab_create(sizeof(struct wy_triplet),
@@ -206,16 +265,21 @@ register_file(struct file_info *finfo, struct spool *spool)
key.spool = spool;
ret = grecs_symtab_lookup_or_install(triplet_table, &key, &install);
+ pthread_mutex_unlock(&triplet_table_mutex);
+
if (!ret)
grecs_alloc_die();
free(key.name);
ret->file[finfo->type] = *finfo;
+
+ triplet_list_lock(&triplet_pending_list);
if (install) {
ret->spool = spool;
ret->acc = grecs_txtacc_create();
- } else
- triplet_list_unlink(ret);
- triplet_list_ordered_insert(ret);
+ } else if (ret->list)
+ triplet_list_unlink(ret->list, ret);
+ triplet_list_ordered_insert(&triplet_pending_list, ret);
+ triplet_list_unlock(&triplet_pending_list);
return ret;
}
@@ -236,33 +300,14 @@ triplet_lookup(struct spool *spool, const char *name)
key.spool = spool;
file_info_cleanup(&finfo);
+ pthread_mutex_lock(&triplet_table_mutex);
ret = grecs_symtab_lookup_or_install(triplet_table, &key, NULL);
+ pthread_mutex_unlock(&triplet_table_mutex);
free(key.name);
return ret;
}
-/* Return true if any part of the triplet TRP was modified more than
- TTL seconds ago */
-static int
-triplet_expired_p(struct wy_triplet *trp)
-{
- int i;
- time_t now = time(NULL);
- time_t ttl = trp->spool->file_sweep_time;
-
- if (ttl == 0)
- return 0;
-
- for (i = 0; i < FILE_TYPE_COUNT; i++) {
- if (trp->file[i].name && (now - trp->file[i].sb.st_mtime) >= ttl) {
- wy_debug(1, (_("file %s expired"), trp->file[i].name));
- return 1;
- }
- }
- return 0;
-}
-
enum triplet_state {
triplet_directive, /* Short triplet: only a directive is present,
but nothing more is required */
@@ -306,6 +351,8 @@ check_triplet_state(struct wy_triplet *trp)
void
triplet_enqueue(struct wy_triplet *trp)
{
+ pthread_t tid;
+
if (!trp)
return;
if (spool_open_dictionaries(trp->spool))
@@ -313,76 +360,62 @@ triplet_enqueue(struct wy_triplet *trp)
switch (check_triplet_state(trp)) {
case triplet_directive:
case triplet_complete:
- if (triplet_expired_p(trp))
- remove_triplet(trp, 0);
- else
- job_schedule_triplet(trp);
+ triplet_list_lock(&triplet_pending_list);
+ triplet_list_unlink(&triplet_pending_list, trp);
+ triplet_list_unlock(&triplet_pending_list);
+
+ triplet_list_lock(&triplet_running_list);
+ triplet_list_insert(&triplet_running_list, trp,
+ triplet_running_list.tail, 1);
+ triplet_list_unlock(&triplet_running_list);
+
+ pthread_create(&tid, NULL, wy_thr_triplet, trp);
break;
case triplet_incomplete:
break;
case triplet_bad:
- remove_triplet(trp, 0);
+ remove_triplet(trp);
}
}
/* Unlink all parts of the triplet TRP */
-int
-remove_triplet(struct wy_triplet *trp, int check)
+static void
+remove_triplet_unlocked(struct wy_triplet *trp)
{
int i;
for (i = 0; i < FILE_TYPE_COUNT; i++) {
if (trp->file[i].name) {
- if (check) {
- struct stat st;
-
- if (wy_dry_run)
- continue;
- if (fstatat(trp->spool->source_fd,
- trp->file[i].name, &st, 0)) {
- if (errno == ENOENT)
- continue;
- else {
+ if (!wy_dry_run) {
+ if (unlinkat(trp->spool->source_fd, trp->file[i].name, 0)) {
+ if (errno != ENOENT)
wy_log(LOG_ERR,
- _("can't stat %s/%s: %s"),
+ _("cannot remove %s/%s: %s"),
trp->spool->source_dir,
trp->file[i].name, strerror(errno));
- return 1;
- }
- } else {
- wy_log(LOG_NOTICE,
- _("%s/%s still exists"),
+ } else
+ wy_log(LOG_NOTICE, _("removing %s/%s"),
trp->spool->source_dir, trp->file[i].name);
- return 1;
- }
- } else {
- wy_log(LOG_NOTICE, _("removing %s/%s"),
- trp->spool->source_dir, trp->file[i].name);
- if (!wy_dry_run
- && unlinkat(trp->spool->source_fd,
- trp->file[i].name, 0))
- wy_log(LOG_ERR,
- _("cannot remove %s/%s: %s"),
- trp->spool->source_dir,
- trp->file[i].name, strerror(errno));
}
}
}
- triplet_list_unlink(trp);
+ triplet_list_unlink(trp->list, trp);
triplet_gpgme_ctx_release(trp);
- grecs_symtab_remove(triplet_table, trp);
- return 0;
+ pthread_mutex_lock(&triplet_table_mutex);
+ grecs_symtab_remove(triplet_table, trp);
+ pthread_mutex_unlock(&triplet_table_mutex);
}
-time_t
-triplet_sweep(void)
+void
+remove_triplet(struct wy_triplet *trp)
{
- while (triplet_list && triplet_expired_p(triplet_list))
- remove_triplet(triplet_list, 0);
+ struct triplet_list *list = trp->list;
- return triplet_ttl(triplet_list);
+ triplet_list_lock(list);
+ remove_triplet_unlocked(trp);
+ triplet_list_unlock(list);
}
void
@@ -392,8 +425,7 @@ triplet_commit(struct wy_triplet *trp)
if (spool_open_dictionaries(trp->spool) == 0) {
timer_start(trp->spool->tag);
wy_debug(1, (_("processing triplet `%s'"), trp->name));
- if (process_directives(trp))
- remove_triplet(trp, 0);
+ process_directives(trp);
timer_stop(trp->spool->tag);
}
timer_stop("spool");
@@ -405,7 +437,7 @@ triplet_remove_file(struct spool *spool, const char *name)
struct wy_triplet *tp = triplet_lookup(spool, name);
int i, n = 0;
- if (!tp)
+ if (!tp || tp->list == &triplet_running_list)
return;
for (i = 0; i < FILE_TYPE_COUNT; i++) {
@@ -420,9 +452,119 @@ triplet_remove_file(struct spool *spool, const char *name)
if (!n) {
wy_debug(1, ("deleting empty triplet (%s/%s)",
spool->source_dir, name));
- remove_triplet(tp, 0);
+ remove_triplet(tp);
}
}
+
+/* Return true if any part of the triplet TRP was modified more than
+ TTL seconds ago */
+static int
+triplet_expired_p(struct wy_triplet *trp)
+{
+ int i;
+ time_t now;
+ time_t ttl;
+
+ if (!trp)
+ return 0;
+
+ now = time(NULL);
+ ttl = trp->spool->file_sweep_time;
+
+ if (ttl == 0)
+ return 0;
+
+ for (i = 0; i < FILE_TYPE_COUNT; i++) {
+ if (trp->file[i].name && (now - trp->file[i].sb.st_mtime) >= ttl) {
+ wy_debug(1, (_("file %s expired"), trp->file[i].name));
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void *
+wy_thr_cleaner(void *ptr)
+{
+ triplet_list_lock(&triplet_pending_list);
+ while (1) {
+ if (triplet_pending_list.head) {
+ struct timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ triplet_ttl(triplet_pending_list.head, &ts);
+ pthread_cond_timedwait(&triplet_pending_list.cond,
+ &triplet_pending_list.mutex, &ts);
+ } else
+ pthread_cond_wait(&triplet_pending_list.cond,
+ &triplet_pending_list.mutex);
+ if (triplet_expired_p(triplet_pending_list.head))
+ remove_triplet_unlocked(triplet_pending_list.head);
+ }
+}
+
+void
+wy_triplet_wait(void)
+{
+ triplet_list_lock(&triplet_running_list);
+ while (triplet_running_list.head) {
+ pthread_cond_wait(&triplet_running_list.cond,
+ &triplet_running_list.mutex);
+ }
+ triplet_list_unlock(&triplet_running_list);
+}
+
+static pthread_key_t key;
+static pthread_once_t key_once = PTHREAD_ONCE_INIT;
+
+static void
+stat_free(void *f)
+{
+ free(f);
+}
+
+static void
+make_key(void)
+{
+ pthread_key_create(&key, stat_free);
+}
+
+WY_STAT_COUNTER *
+wy_get_stat_array(void)
+{
+ WY_STAT_COUNTER *stat;
+ pthread_once(&key_once, make_key);
+ if ((stat = pthread_getspecific(key)) == NULL) {
+ stat = grecs_calloc(WY_MAX_STAT, sizeof(stat[0]));
+ pthread_setspecific(key, stat);
+ }
+ return stat;
+}
+
+WY_STAT_COUNTER *
+wy_get_stat_ptr(int what)
+{
+ WY_STAT_COUNTER *stat;
+ pthread_once(&key_once, make_key);
+ if ((stat = pthread_getspecific(key)) == NULL) {
+ stat = grecs_calloc(WY_MAX_STAT, sizeof(stat[0]));
+ pthread_setspecific(key, stat);
+ }
+ return stat + what;
+}
+
+void *
+wy_thr_triplet(void *ptr)
+{
+ struct wy_triplet *trp = ptr;
+
+ timer_start("wydawca");
+ spool_create_timers();
+ triplet_commit(trp);
+ timer_stop("wydawca");
+ logstats();
+ remove_triplet(trp);
+ return NULL;
+}
/* FIXME */
#define WY_EXP_DFL 0
@@ -844,10 +986,10 @@ expand_triplet_ls_dir(char **ret, struct wy_triplet *trp)
}
DECL_TRIPLET_EXP(real_name, uploader->realname)
- DECL_TRIPLET_EXP(expand_user_email, uploader->email)
+DECL_TRIPLET_EXP(expand_user_email, uploader->email)
- static int
- expand_email_user(char **ret, struct wy_triplet *trp)
+static int
+expand_email_user(char **ret, struct wy_triplet *trp)
{
if (trp && trp->uploader) {
size_t size = 0;
@@ -860,7 +1002,6 @@ DECL_TRIPLET_EXP(real_name, uploader->realname)
return WRDSE_UNDEF;
}
-//FIXME: static env?
static int
expand_report(char **ret, struct wy_triplet *trp)
{
diff --git a/src/wydawca.c b/src/wydawca.c
index d948429..240eca1 100644
--- a/src/wydawca.c
+++ b/src/wydawca.c
@@ -54,18 +54,10 @@ char *wy_gpg_homedir;
char *default_check_script;
struct grecs_sockaddr listen_sockaddr;
-unsigned wydawca_stat[WY_MAX_STAT];
-
unsigned min_directive_version = MIN_DIRECTIVE_VERSION;
unsigned max_directive_version = MAX_DIRECTIVE_VERSION;
int inotify_enable = 1;
-
-void
-initstats()
-{
- memset(wydawca_stat, 0, sizeof wydawca_stat);
-}
/* Logging */
void
@@ -185,9 +177,10 @@ int
wy_stat_mask_p(unsigned long mask)
{
int i;
-
+ WY_STAT_COUNTER *stat = wy_get_stat_array();
+
for (i = 0; i < WY_MAX_STAT; i++)
- if (wydawca_stat[i] != 0 && (mask && WY_STAT_MASK(i)))
+ if (stat[i] != 0 && (mask && WY_STAT_MASK(i)))
return 1;
return 0;
}
@@ -202,7 +195,7 @@ wy_stat_expansion(char **ret, char const *name, size_t len)
&& memcmp(stat_kwname[i], name, len) == 0) {
size_t size = 0;
*ret = NULL;
- if (grecs_asprintf(ret, &size, "%u", wydawca_stat[i]))
+ if (grecs_asprintf(ret, &size, "%u", wy_get_stat_counter(i)))
return WRDSE_NOSPACE;
}
}
@@ -218,7 +211,7 @@ logstats()
for (i = 0; i < WY_MAX_STAT; i++)
if (print_stats & WY_STAT_MASK(i))
wy_log(LOG_INFO, "%s: %u",
- gettext(stat_name[i]), wydawca_stat[i]);
+ gettext(stat_name[i]), wy_get_stat_counter(i));
}
notify_finish();
@@ -270,9 +263,6 @@ grecs_print_diag(grecs_locus_t * locus, int err, int errcode,
}
}
-char **x_argv;
-extern int reconfigure;
-
void
wydawca_daemon()
{
@@ -285,8 +275,6 @@ wydawca_daemon()
}
check_pidfile();
- wydawca_listener();
- remove_pidfile();
}
#include "cmdline.h"
@@ -304,6 +292,75 @@ version_hook(FILE * stream)
putchar('\n');
}
+int fatal_signals[] = {
+ SIGHUP,
+ SIGINT,
+ SIGQUIT,
+ SIGTERM,
+ 0
+};
+
+static void
+sigign(int sig)
+{
+}
+
+void
+wy_main(void)
+{
+ struct sigaction act;
+ sigset_t sigs;
+ int i;
+ pthread_t tid;
+
+ act.sa_flags = 0;
+ sigemptyset(&act.sa_mask);
+ act.sa_handler = sigign;
+
+ /* Block the 'fatal signals' and SIGPIPE in the handling thread */
+ sigemptyset(&sigs);
+ for (i = 0; fatal_signals[i]; i++) {
+ sigaddset(&sigs, fatal_signals[i]);
+ sigaction(fatal_signals[i], &act, NULL);
+ }
+
+ sigaddset(&sigs, SIGPIPE);
+ sigaddset(&sigs, SIGALRM);
+ sigaddset(&sigs, SIGCHLD);
+ pthread_sigmask(SIG_BLOCK, &sigs, NULL);
+
+ scan_all_spools();
+
+ if (wy_mode == WY_MODE_DAEMON) {
+ wydawca_daemon();
+
+ // Start cleaner thread
+ pthread_create(&tid, NULL, wy_thr_cleaner, NULL);
+
+ // Start listener thread
+ pthread_create(&tid, NULL, wy_thr_listen, NULL);
+
+ /* Unblock only the fatal signals */
+ sigemptyset(&sigs);
+ for (i = 0; fatal_signals[i]; i++) {
+ sigaddset(&sigs, fatal_signals[i]);
+ }
+ pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
+
+ /* Wait for signal to arrive */
+ sigwait(&sigs, &i);
+ wy_log(LOG_NOTICE, "shutting down on signal \"%s\"", strsignal(i));
+ } else {
+ /* Unblock only the fatal signals */
+ sigemptyset(&sigs);
+ for (i = 0; fatal_signals[i]; i++) {
+ sigaddset(&sigs, fatal_signals[i]);
+ }
+ pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
+ wy_triplet_wait();
+ }
+}
+
int
main(int argc, char **argv)
{
@@ -314,7 +371,6 @@ main(int argc, char **argv)
proginfo.print_version_hook = version_hook;
config_init();
- x_argv = argv;
parse_options(argc, argv);
wydawca_uid = getuid();
@@ -400,28 +456,16 @@ main(int argc, char **argv)
}
wydawca_lock_init();
- job_init();
wy_log(LOG_NOTICE, _("wydawca (%s) started"), PACKAGE_STRING);
- scan_all_spools();
- if (wy_mode == WY_MODE_DAEMON)
- wydawca_daemon();
- else
- job_queue_wait();
+ wy_main();
dictionaries_close();
modules_close();
+ remove_pidfile();
wy_log(LOG_NOTICE, _("wydawca (%s) finished"), PACKAGE_STRING);
- if (reconfigure) {
- int i;
- for (i = getdtablesize(); i > 2; i--)
- close(i);
- remove_pidfile();
- execv(x_argv[0], x_argv);
- }
-
exit(0);
}
diff --git a/src/wydawca.h b/src/wydawca.h
index 6cc71f1..476f77c 100644
--- a/src/wydawca.h
+++ b/src/wydawca.h
@@ -44,6 +44,7 @@
#include <fnmatch.h>
#include <regex.h>
#include <gpgme.h>
+#include <pthread.h>
#include <mailutils/types.h>
#include <mailutils/errno.h>
@@ -187,7 +188,7 @@ struct wy_triplet {
The prev member points to a triplet older than this one, and next
points to a triplet newer than it: */
struct wy_triplet *prev, *next;
- struct job *job;
+ struct triplet_list *list;
/* User data */
struct wy_user *uploader_list;
struct wy_user *uploader;
@@ -305,7 +306,6 @@ extern int syslog_include_prio; /* Syslog priority indication */
extern time_t file_sweep_time; /* Unlink stale file after this amount of time
*/
extern char *tar_command_name; /* Name of the tar command */
-extern unsigned wydawca_stat[WY_MAX_STAT];
extern unsigned long print_stats;
extern int archive_signatures;
@@ -324,7 +324,6 @@ enum {
};
extern int wy_mode;
-extern time_t wakeup_interval;
extern int foreground;
extern int single_process;
extern struct grecs_sockaddr listen_sockaddr;
@@ -341,11 +340,26 @@ extern int inotify_enable;
extern struct notification *default_notification;
+typedef unsigned WY_STAT_COUNTER;
+WY_STAT_COUNTER *wy_get_stat_array(void);
+
+static inline WY_STAT_COUNTER *
+wy_get_stat_slot(int what)
+{
+ return wy_get_stat_array() + what;
+}
+
+static inline WY_STAT_COUNTER
+wy_get_stat_counter(int what)
+{
+ return *wy_get_stat_slot(what);
+}
+
static inline void
increase_stat_counter(int what)
{
if (what >= WY_MAX_STAT) abort();
- wydawca_stat[what]++;
+ ++*wy_get_stat_slot(what);
}
int stat_mask_p(unsigned long mask);
@@ -394,8 +408,7 @@ char *triplet_expand_dictionary_query(struct dictionary *dict,
void triplet_remove_file(struct spool *spool, const char *name);
-time_t triplet_sweep(void);
-int remove_triplet(struct wy_triplet *trp, int check);
+void remove_triplet(struct wy_triplet *trp);
void triplet_enqueue(struct wy_triplet *trp);
void triplet_commit(struct wy_triplet *trp);
void triplet_gpgme_ctx_release(struct wy_triplet *trp);
@@ -513,45 +526,12 @@ void report_add(const char *fmt, ...);
void report_finish(void);
extern char *report_string;
-/* job.c */
-/* Wydawca job types */
-enum job_type {
- JOB_TRIPLET, /* Process a list of complete triplets */
- JOB_SPOOL, /* Scan single spool */
- JOB_ALL_SPOOLS /* Scan all spools */
-};
-
-void job_schedule(int type, void *data);
-
-static inline void
-job_schedule_all(void)
-{
- job_schedule(JOB_ALL_SPOOLS, NULL);
-}
-
-static inline void
-job_schedule_triplet(struct wy_triplet *tp)
-{
- job_schedule(JOB_TRIPLET, tp);
-}
-
-static inline void
-job_schedule_spool(struct spool *spool)
-{
- job_schedule(JOB_SPOOL, spool);
-}
-
-void job_init(void);
-void job_queue_runner(time_t min_timeout);
-void job_queue_wait(void);
-
-
/* profile.c */
void check_pidfile(void);
void remove_pidfile(void);
/* net.c */
-void wydawca_listener(void);
+void *wy_thr_listen(void *);
void trim_crlf(char *s);
#define LOCK_OK 0
@@ -583,3 +563,6 @@ int watcher_run(int);
int wy_stat_expansion(char **ret, char const *name, size_t len);
FILE *fopenat_ro(int dirfd, char const *name);
+void *wy_thr_triplet(void *ptr);
+void *wy_thr_cleaner(void *ptr);
+void wy_triplet_wait(void);
diff --git a/tests/check-fail.at b/tests/check-fail.at
index 268ca47..400e2e5 100644
--- a/tests/check-fail.at
+++ b/tests/check-fail.at
@@ -22,9 +22,6 @@ AT_DATA([experr],
wydawca: [[NOTICE]] file.directive.asc: VERSION: 1.1
wydawca: [[NOTICE]] file.directive.asc: COMMENT: Gnupload for Wydawca testsuite
wydawca: [[ERR]] spool check script for file@ckfail returned 1
-wydawca: [[NOTICE]] removing ./source/fail/file
-wydawca: [[NOTICE]] removing ./source/fail/file.sig
-wydawca: [[NOTICE]] removing ./source/fail/file.directive.asc
wydawca: [[INFO]] errors: 1
wydawca: [[INFO]] warnings: 0
wydawca: [[INFO]] bad signatures: 0
@@ -39,6 +36,9 @@ wydawca: [[INFO]] files archived: 0
wydawca: [[INFO]] symlinks created: 0
wydawca: [[INFO]] symlinks removed: 0
wydawca: [[INFO]] check failures: 1
+wydawca: [[NOTICE]] removing ./source/fail/file
+wydawca: [[NOTICE]] removing ./source/fail/file.sig
+wydawca: [[NOTICE]] removing ./source/fail/file.directive.asc
wydawca: [[NOTICE]] AT_PACKAGE_TARNAME (AT_PACKAGE_NAME AT_PACKAGE_VERSION) finished
])
diff --git a/tests/check-notify.at b/tests/check-notify.at
index 298ebd0..b064412 100644
--- a/tests/check-notify.at
+++ b/tests/check-notify.at
@@ -22,9 +22,6 @@ AT_DATA([experr],
wydawca: [[NOTICE]] file.directive.asc: VERSION: 1.1
wydawca: [[NOTICE]] file.directive.asc: COMMENT: Gnupload for Wydawca testsuite
wydawca: [[ERR]] spool check script for file@ckfail returned 1
-wydawca: [[NOTICE]] removing ./source/fail/file
-wydawca: [[NOTICE]] removing ./source/fail/file.sig
-wydawca: [[NOTICE]] removing ./source/fail/file.directive.asc
wydawca: [[INFO]] errors: 1
wydawca: [[INFO]] warnings: 0
wydawca: [[INFO]] bad signatures: 0
@@ -39,6 +36,9 @@ wydawca: [[INFO]] files archived: 0
wydawca: [[INFO]] symlinks created: 0
wydawca: [[INFO]] symlinks removed: 0
wydawca: [[INFO]] check failures: 1
+wydawca: [[NOTICE]] removing ./source/fail/file
+wydawca: [[NOTICE]] removing ./source/fail/file.sig
+wydawca: [[NOTICE]] removing ./source/fail/file.directive.asc
wydawca: [[NOTICE]] AT_PACKAGE_TARNAME (AT_PACKAGE_NAME AT_PACKAGE_VERSION) finished
])
diff --git a/tests/inotify-ok.at b/tests/inotify-ok.at
index 5593225..bfe7301 100644
--- a/tests/inotify-ok.at
+++ b/tests/inotify-ok.at
@@ -35,6 +35,7 @@ wydawca: [[INFO]] files archived: 0
wydawca: [[INFO]] symlinks created: 0
wydawca: [[INFO]] symlinks removed: 0
wydawca: [[INFO]] check failures: 0
+wydawca: [[NOTICE]] shutting down on signal "Terminated"
wydawca: [[NOTICE]] AT_PACKAGE_TARNAME (AT_PACKAGE_NAME AT_PACKAGE_VERSION) finished
])
diff --git a/tests/inotify-rmsymlink.at b/tests/inotify-rmsymlink.at
index fa806ac..67819ba 100644
--- a/tests/inotify-rmsymlink.at
+++ b/tests/inotify-rmsymlink.at
@@ -35,6 +35,7 @@ wydawca: [[INFO]] files archived: 0
wydawca: [[INFO]] symlinks created: 0
wydawca: [[INFO]] symlinks removed: 2
wydawca: [[INFO]] check failures: 0
+wydawca: [[NOTICE]] shutting down on signal "Terminated"
wydawca: [[NOTICE]] AT_PACKAGE_TARNAME (AT_PACKAGE_NAME AT_PACKAGE_VERSION) finished
])
diff --git a/tests/inotify-symlink.at b/tests/inotify-symlink.at
index 409804b..dd690ee 100644
--- a/tests/inotify-symlink.at
+++ b/tests/inotify-symlink.at
@@ -35,6 +35,7 @@ wydawca: [[INFO]] files archived: 0
wydawca: [[INFO]] symlinks created: 2
wydawca: [[INFO]] symlinks removed: 0
wydawca: [[INFO]] check failures: 0
+wydawca: [[NOTICE]] shutting down on signal "Terminated"
wydawca: [[NOTICE]] AT_PACKAGE_TARNAME (AT_PACKAGE_NAME AT_PACKAGE_VERSION) finished
])
diff --git a/tests/inotify-unatt00.at b/tests/inotify-unatt00.at
index 1b6dedd..aaba627 100644
--- a/tests/inotify-unatt00.at
+++ b/tests/inotify-unatt00.at
@@ -35,6 +35,7 @@ wydawca: [[INFO]] files archived: 0
wydawca: [[INFO]] symlinks created: 0
wydawca: [[INFO]] symlinks removed: 0
wydawca: [[INFO]] check failures: 0
+wydawca: [[NOTICE]] shutting down on signal "Terminated"
wydawca: [[NOTICE]] AT_PACKAGE_TARNAME (AT_PACKAGE_NAME AT_PACKAGE_VERSION) finished
])
diff --git a/tests/inotify-unatt01.at b/tests/inotify-unatt01.at
index c8c6da6..b198a6e 100644
--- a/tests/inotify-unatt01.at
+++ b/tests/inotify-unatt01.at
@@ -35,6 +35,7 @@ wydawca: [[INFO]] files archived: 0
wydawca: [[INFO]] symlinks created: 0
wydawca: [[INFO]] symlinks removed: 0
wydawca: [[INFO]] check failures: 0
+wydawca: [[NOTICE]] shutting down on signal "Terminated"
wydawca: [[NOTICE]] AT_PACKAGE_TARNAME (AT_PACKAGE_NAME AT_PACKAGE_VERSION) finished
])
diff --git a/tests/upl12f.at b/tests/upl12f.at
index 51d02e9..900b221 100644
--- a/tests/upl12f.at
+++ b/tests/upl12f.at
@@ -22,9 +22,6 @@ AT_DATA([experr],
wydawca: [[NOTICE]] file.directive.asc: VERSION: 1.2
wydawca: [[NOTICE]] file.directive.asc: COMMENT: Gnupload for Wydawca testsuite
wydawca: [[ERR]] refusing to upload file because it already exists and replace is not allowed
-wydawca: [[NOTICE]] removing ./source/test/file
-wydawca: [[NOTICE]] removing ./source/test/file.sig
-wydawca: [[NOTICE]] removing ./source/test/file.directive.asc
wydawca: [[INFO]] errors: 1
wydawca: [[INFO]] warnings: 0
wydawca: [[INFO]] bad signatures: 0
@@ -39,6 +36,9 @@ wydawca: [[INFO]] files archived: 0
wydawca: [[INFO]] symlinks created: 0
wydawca: [[INFO]] symlinks removed: 0
wydawca: [[INFO]] check failures: 0
+wydawca: [[NOTICE]] removing ./source/test/file
+wydawca: [[NOTICE]] removing ./source/test/file.sig
+wydawca: [[NOTICE]] removing ./source/test/file.directive.asc
wydawca: [[NOTICE]] AT_PACKAGE_TARNAME (AT_PACKAGE_NAME AT_PACKAGE_VERSION) finished
])
diff --git a/tests/upload-dry.at b/tests/upload-dry.at
index 7a53e4f..805dc33 100644
--- a/tests/upload-dry.at
+++ b/tests/upload-dry.at
@@ -25,8 +25,6 @@ wydawca: [[DEBUG]] ./source/test -> ./dest
wydawca: [[DEBUG]] Good signature from Wydawca (Testsuite) <bug-wydawca@gnu.org.ua>
wydawca: [[DEBUG]] file: directive file signature OK
wydawca: [[NOTICE]] file.directive.asc: VERSION: 1.1
-wydawca: [[DEBUG]] scheduling job triplet(test,file)
-wydawca: [[DEBUG]] starting job: triplet(test,file)
wydawca: [[DEBUG]] processing triplet `file'
wydawca: [[NOTICE]] file.directive.asc: COMMENT: Gnupload for Wydawca testsuite
wydawca: [[DEBUG]] good detached signature for file
@@ -46,7 +44,6 @@ wydawca: [[INFO]] files archived: 0
wydawca: [[INFO]] symlinks created: 0
wydawca: [[INFO]] symlinks removed: 0
wydawca: [[INFO]] check failures: 0
-wydawca: [[DEBUG]] removing job: triplet(test,file)
wydawca: [[NOTICE]] AT_PACKAGE_TARNAME (AT_PACKAGE_NAME AT_PACKAGE_VERSION) finished
])

Return to:

Send suggestions and report system problems to the System administrator.