This is an automated email from the git hooks/post-receive script.
firstyear pushed a commit to branch master
in repository 389-ds-base.
commit 19f676aa104fb0f4158ed18dfc04d85aba759924
Author: William Brown <firstyear(a)redhat.com>
Date: Tue May 9 10:05:20 2017 +1000
Ticket 49099 - ns workers prep
Bug Description: We wish to move to nunc-stans to control our worker
threads and async tasks.
Fix Description: This first patch moves the NS worker pool
creation to main.c, which makes it accesible to both offline
and online jobs. As well, we no longer "support" a server without
nunc-stans so remove the configure options. We still allow enable
disable of the feature however, so this has been fully tested.
https://pagure.io/389-ds-base/issue/49099
Author: wibrown
Review by: mreynolds (thanks!)
---
configure.ac | 17 --
ldap/servers/slapd/connection.c | 4 -
ldap/servers/slapd/conntable.c | 2 -
ldap/servers/slapd/daemon.c | 253 ++++++----------------------
ldap/servers/slapd/fe.h | 2 +-
ldap/servers/slapd/globals.c | 8 +-
ldap/servers/slapd/libglobs.c | 8 -
ldap/servers/slapd/main.c | 309 ++++++++++++++++++++---------------
ldap/servers/slapd/proto-slap.h | 4 -
ldap/servers/slapd/slap.h | 8 -
src/nunc-stans/ns/ns_thrpool.c | 21 ++-
src/nunc-stans/test/test_nuncstans.c | 74 +++++++++
12 files changed, 320 insertions(+), 390 deletions(-)
diff --git a/configure.ac b/configure.ac
index 5fbf6ac..bfccc2c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -266,23 +266,6 @@ else
fi
AM_CONDITIONAL(enable_posix_winsync,test "$enable_posix_winsync" =
"yes")
-if test -z "$enable_nunc_stans" ; then
- enable_nunc_stans=yes # if not set on cmdline, set default
-fi
-AC_MSG_CHECKING(for --enable-nunc-stans)
-AC_ARG_ENABLE(nunc_stans,
- AS_HELP_STRING([--enable-nunc-stans],
- [enable support for nunc-stans event framework (default: no)]))
-if test "$enable_nunc_stans" = yes ; then
- m4_include(m4/event.m4)
- AC_MSG_RESULT(yes)
- AC_DEFINE([ENABLE_NUNC_STANS], [1], [enable support for nunc-stans event framework])
-else
- AC_MSG_RESULT(no)
-fi
-AM_CONDITIONAL(enable_nunc_stans,test "$enable_nunc_stans" = "yes")
-
-
# the default prefix - override with --prefix or --with-fhs
AC_PREFIX_DEFAULT([/opt/$PACKAGE_NAME])
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
index f6242c3..d3b0f7e 100644
--- a/ldap/servers/slapd/connection.c
+++ b/ldap/servers/slapd/connection.c
@@ -241,10 +241,8 @@ connection_cleanup(Connection *conn)
/* free the connection socket buffer */
connection_free_private_buffer(conn);
-#ifdef ENABLE_NUNC_STANS
/* even if !config_get_enable_nunc_stans, it is ok to set to 0 here */
conn->c_ns_close_jobs = 0;
-#endif
}
/*
@@ -1509,9 +1507,7 @@ connection_threadmain()
Connection *pb_conn = NULL;
Operation *pb_op = NULL;
-#ifdef ENABLE_NUNC_STANS
enable_nunc_stans = config_get_enable_nunc_stans();
-#endif
#if defined( hpux )
/* Arrange to ignore SIGPIPE signals. */
SIGNAL( SIGPIPE, SIG_IGN );
diff --git a/ldap/servers/slapd/conntable.c b/ldap/servers/slapd/conntable.c
index 9e334e2..1c6757d 100644
--- a/ldap/servers/slapd/conntable.c
+++ b/ldap/servers/slapd/conntable.c
@@ -156,10 +156,8 @@ connection_table_get_connection(Connection_Table *ct, int sd)
* far then `c' is not being used by any operation threads, etc.
*/
connection_cleanup(c);
-#ifdef ENABLE_NUNC_STANS
/* NOTE - ok to do this here even if enable_nunc_stans is off */
c->c_ct = ct; /* pointer to connection table that owns this connection */
-#endif
}
else
{
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
index 866eac0..e63c26a 100644
--- a/ldap/servers/slapd/daemon.c
+++ b/ldap/servers/slapd/daemon.c
@@ -87,17 +87,13 @@ static PRLock *diskmon_mutex = NULL;
void disk_monitoring_stop(void);
typedef struct listener_info {
-#ifdef ENABLE_NUNC_STANS
PRStackElem stackelem; /* must be first in struct for PRStack to work */
-#endif
int idx; /* index of this listener in the ct->fd array */
PRFileDesc *listenfd; /* the listener fd */
int secure;
int local;
-#ifdef ENABLE_NUNC_STANS
Connection_Table *ct; /* for listen job callback */
struct ns_job_t *ns_job; /* the ns accept job */
-#endif
} listener_info;
static size_t listeners = 0; /* number of listener sockets */
@@ -117,11 +113,6 @@ static PRFileDesc **createprlistensockets(unsigned short port,
static const char *netaddr2string(const PRNetAddr *addr, char *addrbuf,
size_t addrbuflen);
static void set_shutdown (int);
-#ifdef ENABLE_NUNC_STANS
-struct ns_job_t *ns_signal_job[6];
-static void ns_set_shutdown (struct ns_job_t *job);
-static void ns_set_user (struct ns_job_t *job);
-#endif
static void setup_pr_read_pds(Connection_Table *ct, PRFileDesc **n_tcps, PRFileDesc
**s_tcps, PRFileDesc **i_unix, PRIntn *num_to_read);
#ifdef HPUX10
@@ -161,9 +152,7 @@ accept_and_configure(int s __attribute__((unused)), PRFileDesc
*pr_acceptfd, PRN
*/
/* GGOODREPL static void handle_timeout( void ); */
static int handle_new_connection(Connection_Table *ct, int tcps, PRFileDesc *pr_acceptfd,
int secure, int local, Connection **newconn );
-#ifdef ENABLE_NUNC_STANS
static void ns_handle_new_connection(struct ns_job_t *job);
-#endif
static void handle_pr_read_ready(Connection_Table *ct, PRIntn num_poll);
static int clear_signal(struct POLL_STRUCT *fds);
static void unfurl_banners(Connection_Table *ct,daemon_ports_t *ports, PRFileDesc
**n_tcps, PRFileDesc **s_tcps, PRFileDesc **i_unix);
@@ -916,58 +905,7 @@ convert_pbe_des_to_aes(void)
charray_free(attrs);
}
-#ifdef ENABLE_NUNC_STANS
-/*
- * Nunc stans logging function.
- */
-static void
-nunc_stans_logging(int severity, const char *format, va_list varg)
-{
- va_list varg_copy;
- int loglevel = SLAPI_LOG_ERR;
-
- if (severity == LOG_DEBUG){
- loglevel = SLAPI_LOG_NUNCSTANS;
- } else if(severity == LOG_INFO){
- loglevel = SLAPI_LOG_CONNS;
- }
- va_copy(varg_copy, varg);
- slapi_log_error_ext(loglevel, "nunc-stans", (char *)format, varg, varg_copy);
- va_end(varg_copy);
-}
-
-static void*
-nunc_stans_malloc(size_t size)
-{
- return (void*)slapi_ch_malloc((unsigned long)size);
-}
-
-static void*
-nunc_stans_memalign(size_t size, size_t alignment)
-{
- return (void*)slapi_ch_memalign(size, alignment);
-}
-
-static void*
-nunc_stans_calloc(size_t count, size_t size)
-{
- return (void*)slapi_ch_calloc((unsigned long)count, (unsigned long)size);
-}
-
-static void*
-nunc_stans_realloc(void *block, size_t size)
-{
- return (void*)slapi_ch_realloc((char *)block, (unsigned long)size);
-}
-
-static void
-nunc_stans_free(void *ptr)
-{
- slapi_ch_free((void **)&ptr);
-}
-#endif /* ENABLE_NUNC_STANS */
-
-void slapd_daemon( daemon_ports_t *ports )
+void slapd_daemon( daemon_ports_t *ports, ns_thrpool_t *tp )
{
/* We are passed some ports---one for regular connections, one
* for SSL connections, one for ldapi connections.
@@ -986,16 +924,10 @@ void slapd_daemon( daemon_ports_t *ports )
PRThread *time_thread_p;
int threads;
int in_referral_mode = config_check_referral_mode();
-#ifdef ENABLE_NUNC_STANS
- ns_thrpool_t *tp = NULL;
- struct ns_thrpool_config tp_config;
-#endif
int connection_table_size = get_configured_connection_table_size();
the_connection_table= connection_table_new(connection_table_size);
-#ifdef ENABLE_NUNC_STANS
enable_nunc_stans = config_get_enable_nunc_stans();
-#endif
#ifdef RESOLVER_NEEDS_LOW_FILE_DESCRIPTORS
/*
@@ -1022,38 +954,6 @@ void slapd_daemon( daemon_ports_t *ports )
createsignalpipe();
/* Setup our signal interception. */
init_shutdown_detect();
-#ifdef ENABLE_NUNC_STANS
- } else {
- PRInt32 maxthreads = (PRInt32)config_get_threadnumber();
- /* Set the nunc-stans thread pool config */
- ns_thrpool_config_init(&tp_config);
-
- tp_config.max_threads = maxthreads;
- tp_config.stacksize = SLAPD_DEFAULT_THREAD_STACKSIZE;
-#ifdef LDAP_ERROR_LOGGING
- tp_config.log_fct = nunc_stans_logging;
-#else
- tp_config.log_fct = NULL;
-#endif
- tp_config.log_start_fct = NULL;
- tp_config.log_close_fct = NULL;
- tp_config.malloc_fct = nunc_stans_malloc;
- tp_config.memalign_fct = nunc_stans_memalign;
- tp_config.calloc_fct = nunc_stans_calloc;
- tp_config.realloc_fct = nunc_stans_realloc;
- tp_config.free_fct = nunc_stans_free;
-
- tp = ns_thrpool_new(&tp_config);
-
- /* We mark these as persistent so they keep blocking signals forever. */
- /* These *must* be in the event thread (ie not ns_job_thread) to prevent races
*/
- ns_add_signal_job(tp, SIGINT, NS_JOB_PERSIST, ns_set_shutdown, NULL,
&ns_signal_job[0]);
- ns_add_signal_job(tp, SIGTERM, NS_JOB_PERSIST, ns_set_shutdown, NULL,
&ns_signal_job[1]);
- ns_add_signal_job(tp, SIGTSTP, NS_JOB_PERSIST, ns_set_shutdown, NULL,
&ns_signal_job[3]);
- ns_add_signal_job(tp, SIGHUP, NS_JOB_PERSIST, ns_set_user, NULL,
&ns_signal_job[2]);
- ns_add_signal_job(tp, SIGUSR1, NS_JOB_PERSIST, ns_set_user, NULL,
&ns_signal_job[4]);
- ns_add_signal_job(tp, SIGUSR2, NS_JOB_PERSIST, ns_set_user, NULL,
&ns_signal_job[5]);
-#endif /* ENABLE_NUNC_STANS */
}
if (
@@ -1180,7 +1080,6 @@ void slapd_daemon( daemon_ports_t *ports )
*/
convert_pbe_des_to_aes();
-#ifdef ENABLE_NUNC_STANS
if (enable_nunc_stans && !g_get_shutdown()) {
setup_pr_read_pds(the_connection_table,n_tcps,s_tcps,i_unix,&num_poll);
for (size_t ii = 0; ii < listeners; ++ii) {
@@ -1190,7 +1089,6 @@ void slapd_daemon( daemon_ports_t *ports )
}
}
-#endif /* ENABLE_NUNC_STANS */
/* Now we write the pid file, indicating that the server is finally and listening for
connections */
write_pid_file();
@@ -1205,42 +1103,55 @@ void slapd_daemon( daemon_ports_t *ports )
);
#endif
-#ifdef ENABLE_NUNC_STANS
- if (enable_nunc_stans && ns_thrpool_wait(tp)) {
- slapi_log_err(SLAPI_LOG_ERR,
- "slapd-daemon", "ns_thrpool_wait failed errno %d (%s)\n",
errno,
- slapd_system_strerror(errno));
- }
-#endif
- /* The meat of the operation is in a loop on a call to select */
- while(!enable_nunc_stans && !g_get_shutdown())
- {
- int select_return = 0;
- PRErrorCode prerr;
+ if (enable_nunc_stans) {
+ if (ns_thrpool_wait(tp)) {
+ slapi_log_err(SLAPI_LOG_ERR,
+ "slapd-daemon", "ns_thrpool_wait failed errno %d
(%s)\n", errno,
+ slapd_system_strerror(errno));
+ }
- setup_pr_read_pds(the_connection_table,n_tcps,s_tcps,i_unix,&num_poll);
- select_return = POLL_FN(the_connection_table->fd, num_poll, pr_timeout);
- switch (select_return) {
- case 0: /* Timeout */
- /* GGOODREPL handle_timeout(); */
- break;
- case -1: /* Error */
- prerr = PR_GetError();
- slapi_log_err(SLAPI_LOG_TRACE, "slapd_daemon", "PR_Poll() failed,
"
- SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
- prerr, slapd_system_strerror(prerr));
- break;
- default: /* either a new connection or some new data ready */
- /* handle new connections from the listeners */
- handle_listeners(the_connection_table);
- /* handle new data ready */
- handle_pr_read_ready(the_connection_table, connection_table_size);
- clear_signal(the_connection_table->fd);
- break;
- }
- }
- /* We get here when the server is shutting down */
- /* Do what we have to do before death */
+ /* we have exited from ns_thrpool_wait. This means we are shutting down! */
+ /* Please see
https://firstyear.fedorapeople.org/nunc-stans/md_docs_job-safety.html */
+ /* tldr is shutdown needs to run first to allow job_done on an ARMED job */
+ for (size_t i = 0; i < listeners; i++) {
+ PRStatus shutdown_status = ns_job_done(listener_idxs[i].ns_job);
+ if (shutdown_status != PR_SUCCESS) {
+ slapi_log_err(SLAPI_LOG_CRIT, "ns_set_shutdown", "Failed
to shutdown listener idx %"PRIu64" !\n", i);
+ }
+ PR_ASSERT(shutdown_status == PR_SUCCESS);
+ listener_idxs[i].ns_job = NULL;
+ }
+ } else {
+ /* The meat of the operation is in a loop on a call to select */
+ while(!g_get_shutdown())
+ {
+ int select_return = 0;
+ PRErrorCode prerr;
+
+ setup_pr_read_pds(the_connection_table,n_tcps,s_tcps,i_unix,&num_poll);
+ select_return = POLL_FN(the_connection_table->fd, num_poll, pr_timeout);
+ switch (select_return) {
+ case 0: /* Timeout */
+ /* GGOODREPL handle_timeout(); */
+ break;
+ case -1: /* Error */
+ prerr = PR_GetError();
+ slapi_log_err(SLAPI_LOG_TRACE, "slapd_daemon", "PR_Poll()
failed, "
+ SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
+ prerr, slapd_system_strerror(prerr));
+ break;
+ default: /* either a new connection or some new data ready */
+ /* handle new connections from the listeners */
+ handle_listeners(the_connection_table);
+ /* handle new data ready */
+ handle_pr_read_ready(the_connection_table, connection_table_size);
+ clear_signal(the_connection_table->fd);
+ break;
+ }
+ }
+ /* We get here when the server is shutting down */
+ /* Do what we have to do before death */
+ }
#ifdef WITH_SYSTEMD
sd_notify(0, "STOPPING=1");
@@ -1374,27 +1285,6 @@ void slapd_daemon( daemon_ports_t *ports )
*/
log_access_flush();
-#ifdef ENABLE_NUNC_STANS
-
- /*
- * We need to shutdown the nunc-stans thread pool before we free the
- * connection table.
- */
- if (enable_nunc_stans) {
- /* Now we free the signal jobs. We do it late here to keep intercepting
- * them for as long as possible .... Later we need to rethink this to
- * have plugins and such destroy while the tp is still active.
- */
- ns_job_done(ns_signal_job[0]);
- ns_job_done(ns_signal_job[1]);
- ns_job_done(ns_signal_job[2]);
- ns_job_done(ns_signal_job[3]);
- ns_job_done(ns_signal_job[4]);
- ns_job_done(ns_signal_job[5]);
-
- ns_thrpool_destroy(tp);
- }
-#endif
/*
* connection_table_free could use callbacks in the backend.
* (e.g., be_search_results_release)
@@ -1804,7 +1694,6 @@ handle_pr_read_ready(Connection_Table *ct, PRIntn num_poll
__attribute__((unused
}
}
-#ifdef ENABLE_NUNC_STANS
#define CONN_NEEDS_CLOSING(c) (c->c_flags & CONN_FLAG_CLOSING) || (c->c_sd ==
SLAPD_INVALID_SOCKET)
/* Used internally by ns_handle_closure and ns_handle_pr_read_ready.
* Returns 0 if the connection was successfully closed, or 1 otherwise.
@@ -1859,7 +1748,6 @@ ns_handle_closure(struct ns_job_t *job)
}
return;
}
-#endif
/**
* Schedule more I/O for this connection, or make sure that it
@@ -1868,7 +1756,6 @@ ns_handle_closure(struct ns_job_t *job)
void
ns_connection_post_io_or_closing(Connection *conn)
{
-#ifdef ENABLE_NUNC_STANS
struct timeval tv;
if (!enable_nunc_stans) {
@@ -1941,10 +1828,8 @@ ns_connection_post_io_or_closing(Connection *conn)
"conn %" PRIu64 " for fd=%d\n", conn->c_connid,
conn->c_sd);
}
}
-#endif
}
-#ifdef ENABLE_NUNC_STANS
/* This function must be called without the thread flag, in the
* event loop. This function may free the connection. This can
* only be done in the event loop thread.
@@ -2025,7 +1910,6 @@ ns_handle_pr_read_ready(struct ns_job_t *job)
ns_job_done(job);
return;
}
-#endif
/*
* wrapper functions required so we can implement ioblock_timeout and
@@ -2634,7 +2518,6 @@ handle_new_connection(Connection_Table *ct, int tcps, PRFileDesc
*pr_acceptfd, i
return 0;
}
-#ifdef ENABLE_NUNC_STANS
static void
ns_handle_new_connection(struct ns_job_t *job)
{
@@ -2680,7 +2563,6 @@ ns_handle_new_connection(struct ns_job_t *job)
ns_connection_post_io_or_closing(c);
return;
}
-#endif
static int init_shutdown_detect(void)
{
@@ -2856,43 +2738,6 @@ set_shutdown (int sig __attribute__((unused)))
(void) SIGNAL( SIGHUP, set_shutdown );
}
-#ifdef ENABLE_NUNC_STANS
-static void
-ns_set_user(struct ns_job_t *job __attribute__((unused)))
-{
- /* This literally does nothing. We intercept user signals (USR1, USR2) */
- /* Could be good for a status output, or an easter egg. */
- return;
-}
-
-static void
-ns_set_shutdown(struct ns_job_t *job)
-{
- /* Is there a way to make this a bit more atomic? */
- /* I think NS protects this by only executing one signal job at a time */
- PRStatus shutdown_status = PR_SUCCESS;
-
- if (g_get_shutdown() == 0) {
- g_set_shutdown(SLAPI_SHUTDOWN_SIGNAL);
-
- /* Signal all the worker threads to stop */
- ns_thrpool_shutdown(ns_job_get_tp(job));
-
- /* Stop all the long running jobs */
- /* Please see
https://firstyear.fedorapeople.org/nunc-stans/md_docs_job-safety.html */
- /* tldr is shutdown needs to run first to allow job_done on an ARMED job */
- for (size_t i = 0; i < listeners; i++) {
- shutdown_status = ns_job_done(listener_idxs[i].ns_job);
- if (shutdown_status != PR_SUCCESS) {
- slapi_log_err(SLAPI_LOG_CRIT, "ns_set_shutdown", "Failed
to shutdown listener idx %"PRIu64" !\n", i);
- }
- PR_ASSERT(shutdown_status == PR_SUCCESS);
- listener_idxs[i].ns_job = NULL;
- }
- }
-}
-#endif
-
#ifndef LINUX
void
slapd_do_nothing (int sig)
diff --git a/ldap/servers/slapd/fe.h b/ldap/servers/slapd/fe.h
index 3d9ac08..9667997 100644
--- a/ldap/servers/slapd/fe.h
+++ b/ldap/servers/slapd/fe.h
@@ -116,7 +116,7 @@ int connection_table_iterate_active_connections(Connection_Table *ct,
void* arg,
*/
int signal_listner(void);
int daemon_pre_setuid_init(daemon_ports_t *ports);
-void slapd_daemon( daemon_ports_t *ports );
+void slapd_daemon( daemon_ports_t *ports, ns_thrpool_t *tp );
void daemon_register_connection(void);
int slapd_listenhost2addr( const char *listenhost, PRNetAddr ***addr );
int daemon_register_reslimits( void );
diff --git a/ldap/servers/slapd/globals.c b/ldap/servers/slapd/globals.c
index 003ffed..936c92e 100644
--- a/ldap/servers/slapd/globals.c
+++ b/ldap/servers/slapd/globals.c
@@ -38,10 +38,10 @@
#include "slap.h"
#include "fe.h"
-int should_detach = 1;
-time_t starttime;
-PRThread *listener_tid;
-Slapi_PBlock *repl_pb = NULL;
+int should_detach = 0;
+time_t starttime;
+PRThread *listener_tid;
+Slapi_PBlock *repl_pb = NULL;
/*
* global variables that need mutex protection
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index e488885..7b338b3 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -241,9 +241,7 @@ slapi_onoff_t init_ignore_time_skew;
slapi_onoff_t init_dynamic_plugins;
slapi_onoff_t init_cn_uses_dn_syntax_in_dns;
slapi_onoff_t init_global_backend_local;
-#ifdef ENABLE_NUNC_STANS
slapi_onoff_t init_enable_nunc_stans;
-#endif
#if defined (LINUX)
slapi_int_t init_malloc_mxfast;
slapi_int_t init_malloc_trim_threshold;
@@ -1099,12 +1097,10 @@ static struct config_get_and_set {
NULL, 0,
(void**)&global_slapdFrontendConfig.maxsimplepaged_per_conn,
CONFIG_INT, (ConfigGetFunc)config_get_maxsimplepaged_per_conn,
SLAPD_DEFAULT_MAXSIMPLEPAGED_PER_CONN_STR},
-#ifdef ENABLE_NUNC_STANS
{CONFIG_ENABLE_NUNC_STANS, config_set_enable_nunc_stans,
NULL, 0,
(void**)&global_slapdFrontendConfig.enable_nunc_stans,
CONFIG_ON_OFF, (ConfigGetFunc)config_get_enable_nunc_stans,
&init_enable_nunc_stans},
-#endif
#ifdef MEMPOOL_EXPERIMENTAL
{CONFIG_MEMPOOL_SWITCH_ATTRIBUTE, config_set_mempool_switch,
NULL, 0,
@@ -1667,9 +1663,7 @@ FrontendConfig_init(void) {
cfg->maxbersize = SLAPD_DEFAULT_MAXBERSIZE;
cfg->logging_backend = slapi_ch_strdup(SLAPD_INIT_LOGGING_BACKEND_INTERNAL);
cfg->rootdn = slapi_ch_strdup(SLAPD_DEFAULT_DIRECTORY_MANAGER);
-#ifdef ENABLE_NUNC_STANS
init_enable_nunc_stans = cfg->enable_nunc_stans = LDAP_ON;
-#endif
#if defined(LINUX)
init_malloc_mxfast = cfg->malloc_mxfast = DEFAULT_MALLOC_UNSET;
init_malloc_trim_threshold = cfg->malloc_trim_threshold = DEFAULT_MALLOC_UNSET;
@@ -7488,7 +7482,6 @@ config_get_listen_backlog_size()
return retVal;
}
-#ifdef ENABLE_NUNC_STANS
int
config_get_enable_nunc_stans()
{
@@ -7513,7 +7506,6 @@ config_set_enable_nunc_stans( const char *attrname, char *value,
errorbuf, apply);
return retVal;
}
-#endif
static char *
config_initvalue_to_onoff(struct config_get_and_set *cgas, char *initvalbuf, size_t
initvalbufsize)
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
index 3364a01..0d79aba 100644
--- a/ldap/servers/slapd/main.c
+++ b/ldap/servers/slapd/main.c
@@ -78,89 +78,162 @@ static int slapd_exemode_suffix2instance(void);
static int slapd_debug_level_string2level( const char *s );
static void slapd_debug_level_log( int level );
static void slapd_debug_level_usage( void );
-static void cmd_set_shutdown(int);
/*
* global variables
*/
static int slapd_exemode = SLAPD_EXEMODE_UNKNOWN;
-static int init_cmd_shutdown_detect(void)
+
+struct ns_job_t *ns_signal_job[6];
+
+/*
+ * Nunc stans logging function.
+ */
+static void
+nunc_stans_logging(int severity, const char *format, va_list varg)
{
+ va_list varg_copy;
+ int loglevel = SLAPI_LOG_ERR;
- /* First of all, we must reset the signal mask to get rid of any blockages
- * the process may have inherited from its parent (such as the console), which
- * might result in the process not delivering those blocked signals, and thus,
- * misbehaving....
- */
- {
- int rc;
- sigset_t proc_mask;
-
- slapi_log_err(SLAPI_LOG_TRACE, "init_cmd_shutdown_detect", "Reseting
signal mask...\n");
- (void)sigemptyset( &proc_mask );
- rc = pthread_sigmask( SIG_SETMASK, &proc_mask, NULL );
- slapi_log_err(SLAPI_LOG_TRACE, "init_cmd_shutdown_detect",
"%s\n",
- rc ? "Failed to reset signal mask":"...Done (signal mask
reset)!!");
- }
+ if (severity == LOG_DEBUG){
+ loglevel = SLAPI_LOG_NUNCSTANS;
+ } else if(severity == LOG_INFO){
+ loglevel = SLAPI_LOG_CONNS;
+ }
-#if defined ( HPUX10 )
- PR_CreateThread ( PR_USER_THREAD,
- catch_signals,
- NULL,
- PR_PRIORITY_NORMAL,
- PR_GLOBAL_THREAD,
- PR_UNJOINABLE_THREAD,
- SLAPD_DEFAULT_THREAD_STACKSIZE);
-#elif defined ( HPUX11 )
- /* In the optimized builds for HPUX, the signal handler doesn't seem
- * to get set correctly unless the primordial thread gets a chance
- * to run before we make the call to SIGNAL. (At this point the
- * the primordial thread has spawned the daemon thread which called
- * this function.) The call to DS_Sleep will give the primordial
- * thread a chance to run. */
- DS_Sleep(0);
-#endif
+ va_copy(varg_copy, varg);
+ slapi_log_error_ext(loglevel, "nunc-stans", (char *)format, varg,
varg_copy);
+ va_end(varg_copy);
+}
- (void) SIGNAL( SIGPIPE, SIG_IGN );
- (void) SIGNAL( SIGCHLD, slapd_wait4child );
-#ifndef LINUX
- /* linux uses USR1/USR2 for thread synchronization, so we aren't
- * allowed to mess with those.
- */
- (void) SIGNAL( SIGUSR1, slapd_do_nothing );
- (void) SIGNAL( SIGUSR2, cmd_set_shutdown );
-#endif
- (void) SIGNAL( SIGTERM, cmd_set_shutdown );
- (void) SIGNAL( SIGHUP, cmd_set_shutdown );
- (void) SIGNAL( SIGINT, cmd_set_shutdown );
+static void
+ns_printf_logger(int priority __attribute__((unused)), const char *fmt, va_list varg)
+{
+ /* Should we do anything with priority? */
+ vprintf(fmt, varg);
+}
- return 0;
+static void*
+nunc_stans_malloc(size_t size)
+{
+ return (void*)slapi_ch_malloc((unsigned long)size);
+}
+
+static void*
+nunc_stans_memalign(size_t size, size_t alignment)
+{
+ return (void*)slapi_ch_memalign(size, alignment);
+}
+
+static void*
+nunc_stans_calloc(size_t count, size_t size)
+{
+ return (void*)slapi_ch_calloc((unsigned long)count, (unsigned long)size);
+}
+
+static void*
+nunc_stans_realloc(void *block, size_t size)
+{
+ return (void*)slapi_ch_realloc((char *)block, (unsigned long)size);
}
static void
-cmd_set_shutdown (int sig __attribute__((unused)))
+nunc_stans_free(void *ptr)
{
- /* don't log anything from a signal handler:
- * you could be holding a lock when the signal was trapped. more
- * specifically, you could be holding the logfile lock (and deadlock
- * yourself).
- */
+ slapi_ch_free((void **)&ptr);
+}
- c_set_shutdown();
-#ifndef LINUX
- /* don't mess with USR1/USR2 on linux, used by libpthread */
- (void) SIGNAL( SIGUSR2, cmd_set_shutdown );
-#endif
- (void) SIGNAL( SIGTERM, cmd_set_shutdown );
- (void) SIGNAL( SIGHUP, cmd_set_shutdown );
+static void
+ns_set_user(struct ns_job_t *job __attribute__((unused)))
+{
+ /* This literally does nothing. We intercept user signals (USR1, USR2) */
+ /* Could be good for a status output, or an easter egg. */
+ return;
}
-#ifdef HPUX10
-extern void collation_init();
+static void
+ns_set_shutdown(struct ns_job_t *job)
+{
+ /* Is there a way to make this a bit more atomic? */
+ /* I think NS protects this by only executing one signal job at a time */
+ if (g_get_shutdown() == 0) {
+ g_set_shutdown(SLAPI_SHUTDOWN_SIGNAL);
+
+ /* Signal all the worker threads to stop */
+ }
+ ns_thrpool_shutdown(ns_job_get_tp(job));
+}
+
+
+/*
+ * Setup our nunc-stans worker pool from our config.
+ * we must have read dse.ldif before this point.
+ */
+
+static int_fast32_t
+main_create_ns(ns_thrpool_t **tp_in) {
+ if (!config_get_enable_nunc_stans()) {
+ return 1;
+ }
+ struct ns_thrpool_config tp_config;
+
+ int32_t maxthreads = (int32_t)config_get_threadnumber();
+ /* Set the nunc-stans thread pool config */
+ ns_thrpool_config_init(&tp_config);
+
+ tp_config.max_threads = maxthreads;
+ tp_config.stacksize = SLAPD_DEFAULT_THREAD_STACKSIZE;
+ /* Highly likely that we need to re-write logging to be controlled by NS here. */
+ /* tp_config.log_fct = nunc_stans_logging; */
+#ifdef DEBUG
+ tp_config.log_fct = ns_printf_logger;
#endif
+ tp_config.log_start_fct = NULL;
+ tp_config.log_close_fct = NULL;
+ tp_config.malloc_fct = nunc_stans_malloc;
+ tp_config.memalign_fct = nunc_stans_memalign;
+ tp_config.calloc_fct = nunc_stans_calloc;
+ tp_config.realloc_fct = nunc_stans_realloc;
+ tp_config.free_fct = nunc_stans_free;
+
+ *tp_in = ns_thrpool_new(&tp_config);
+
+ /* We mark these as persistent so they keep blocking signals forever. */
+ /* These *must* be in the event thread (ie not ns_job_thread) to prevent races */
+ ns_add_signal_job(*tp_in, SIGINT, NS_JOB_PERSIST, ns_set_shutdown, NULL,
&ns_signal_job[0]);
+ ns_add_signal_job(*tp_in, SIGTERM, NS_JOB_PERSIST, ns_set_shutdown, NULL,
&ns_signal_job[1]);
+ ns_add_signal_job(*tp_in, SIGTSTP, NS_JOB_PERSIST, ns_set_shutdown, NULL,
&ns_signal_job[3]);
+ ns_add_signal_job(*tp_in, SIGHUP, NS_JOB_PERSIST, ns_set_user, NULL,
&ns_signal_job[2]);
+ ns_add_signal_job(*tp_in, SIGUSR1, NS_JOB_PERSIST, ns_set_user, NULL,
&ns_signal_job[4]);
+ ns_add_signal_job(*tp_in, SIGUSR2, NS_JOB_PERSIST, ns_set_user, NULL,
&ns_signal_job[5]);
+ return 0;
+}
-/*
+static int_fast32_t
+main_stop_ns(ns_thrpool_t *tp) {
+ if (tp == NULL) {
+ return 0;
+ }
+ ns_thrpool_shutdown(tp);
+ ns_thrpool_wait(tp);
+
+ /* Now we free the signal jobs. We do it late here to keep intercepting
+ * them for as long as possible .... Later we need to rethink this to
+ * have plugins and such destroy while the tp is still active.
+ */
+ ns_job_done(ns_signal_job[0]);
+ ns_job_done(ns_signal_job[1]);
+ ns_job_done(ns_signal_job[2]);
+ ns_job_done(ns_signal_job[3]);
+ ns_job_done(ns_signal_job[4]);
+ ns_job_done(ns_signal_job[5]);
+ ns_thrpool_destroy(tp);
+
+ return 0;
+}
+
+/*
Four cases:
- change ownership of all files in directory (strip_fn=PR_FALSE)
- change ownership of all files in directory; but trailing fn needs to be stripped
(strip_fn=PR_TRUE)
@@ -579,12 +652,8 @@ main( int argc, char **argv)
int return_value = 0;
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
daemon_ports_t ports_info = {0};
-#ifndef __LP64__
-#if defined(__hpux) && !defined(__ia64)
- /* for static constructors */
- _main();
-#endif
-#endif
+ ns_thrpool_t *tp = NULL;
+
#ifdef MEMPOOL_EXPERIMENTAL
/* to use LDAP C SDK lber functions seemlessly with slapi_ch_malloc funcs,
* setting the slapi_ch_malloc funcs to lber option here. */
@@ -775,14 +844,6 @@ main( int argc, char **argv)
raise_process_limits(); /* should be done ASAP once config file read */
-#ifdef PUMPKIN_HOUR
- if ( time( NULL ) > (PUMPKIN_HOUR - 10) ) {
- slapi_log_err(SLAPI_LOG_ERR, "main",
- "ERROR: ** This beta software has expired **\n");
- exit( 1 );
- }
-#endif
-
/* Set entry points in libslapd */
set_entry_points();
@@ -855,15 +916,22 @@ main( int argc, char **argv)
exit(1);
}
- /* Do NSS and/or SSL init for those modes other than listening modes */
- if ((slapd_exemode != SLAPD_EXEMODE_REFERRAL) &&
- (slapd_exemode != SLAPD_EXEMODE_SLAPD)) {
- if (slapd_do_all_nss_ssl_init(slapd_exemode, importexport_encrypt,
- s_port, &ports_info)) {
- return_value = 1;
- goto cleanup;
- }
- }
+ /*
+ * Detach ourselves from the terminal (unless running in debug mode).
+ * We must detach before we start any threads since detach forks() on
+ * UNIX.
+ * Have to detach after ssl_init - the user may be prompted for the PIN
+ * on the terminal, so it must be open.
+ */
+ if (detach(slapd_exemode, importexport_encrypt, s_port, &ports_info)) {
+ return_value = 1;
+ goto cleanup;
+ }
+
+ /*
+ * Create our thread pool here for tasks to utilise.
+ */
+ main_create_ns(&tp);
/*
* if we were called upon to do special database stuff, do it and be
@@ -955,35 +1023,23 @@ main( int argc, char **argv)
ndn_cache_init();
global_backend_lock_init();
- /*
- * Detach ourselves from the terminal (unless running in debug mode).
- * We must detach before we start any threads since detach forks() on
- * UNIX.
- * Have to detach after ssl_init - the user may be prompted for the PIN
- * on the terminal, so it must be open.
- */
- if (detach(slapd_exemode, importexport_encrypt,
- s_port, &ports_info)) {
- return_value = 1;
- goto cleanup;
- }
- /*
- * Now write our PID to the startup PID file.
- * This is used by the start up script to determine our PID quickly
- * after we fork, without needing to wait for the 'real' pid file to be
- * written. That could take minutes. And the start script will wait
- * that long looking for it. With this new 'early pid' file, it can avoid
- * doing that, by detecting the pid and watching for the process exiting.
- * This removes the blank stares all round from start-slapd when the server
- * fails to start for some reason
- */
- write_start_pid_file();
+ /*
+ * Now write our PID to the startup PID file.
+ * This is used by the start up script to determine our PID quickly
+ * after we fork, without needing to wait for the 'real' pid file to be
+ * written. That could take minutes. And the start script will wait
+ * that long looking for it. With this new 'early pid' file, it can avoid
+ * doing that, by detecting the pid and watching for the process exiting.
+ * This removes the blank stares all round from start-slapd when the server
+ * fails to start for some reason
+ */
+ write_start_pid_file();
/* Make sure we aren't going to run slapd in
* a mode that is going to conflict with other
- * slapd processes that are currently running
- */
+ * slapd processes that are currently running
+ */
if ((slapd_exemode != SLAPD_EXEMODE_REFERRAL) &&
( add_new_slapd_process(slapd_exemode, db2ldif_dump_replica,
skip_db_protect_check) == -1 ))
@@ -1001,12 +1057,12 @@ main( int argc, char **argv)
* stderr and our error log. Yuck.
*/
if (1) {
- char *versionstring = config_get_versionstring();
- char *buildnum = config_get_buildnum();
- slapi_log_err(SLAPI_LOG_INFO, "main", "%s B%s starting up\n",
+ char *versionstring = config_get_versionstring();
+ char *buildnum = config_get_buildnum();
+ slapi_log_err(SLAPI_LOG_INFO, "main", "%s B%s starting up\n",
versionstring, buildnum);
- slapi_ch_free((void **)&buildnum);
- slapi_ch_free((void **)&versionstring);
+ slapi_ch_free((void **)&buildnum);
+ slapi_ch_free((void **)&versionstring);
}
/* -sduloutre: compute_init() and entry_computed_attr_init() moved up */
@@ -1142,7 +1198,7 @@ main( int argc, char **argv)
{
time( &starttime );
- slapd_daemon(&ports_info);
+ slapd_daemon(&ports_info, tp);
}
slapi_log_err(SLAPI_LOG_INFO, "main", "slapd stopped.\n");
reslimit_cleanup();
@@ -1154,12 +1210,9 @@ cleanup:
SSL_ClearSessionCache();
ndn_cache_destroy();
NSS_Shutdown();
+ main_stop_ns(tp);
PR_Cleanup();
-#if defined( hpux )
- exit( return_value );
-#else
return return_value;
-#endif
}
@@ -1411,7 +1464,6 @@ process_command_line(int argc, char **argv, char **extraname)
long_opts = long_options_archive2db;
break;
case SLAPD_EXEMODE_DB2ARCHIVE:
- init_cmd_shutdown_detect();
opts = opts_db2archive;
long_opts = long_options_db2archive;
break;
@@ -1420,6 +1472,8 @@ process_command_line(int argc, char **argv, char **extraname)
long_opts = long_options_db2index;
break;
case SLAPD_EXEMODE_REFERRAL:
+ /* Default to not detaching, but if REFERRAL, turn it on. */
+ should_detach = 1;
opts = opts_referral;
long_opts = long_options_referral;
break;
@@ -1440,6 +1494,8 @@ process_command_line(int argc, char **argv, char **extraname)
long_opts = long_options_dbverify;
break;
default: /* SLAPD_EXEMODE_SLAPD */
+ /* Default to not detaching, but if SLAPD, turn it on. */
+ should_detach = 1;
opts = opts_slapd;
long_opts = long_options_slapd;
}
@@ -2105,7 +2161,6 @@ slapd_exemode_ldif2db(void)
slapi_pblock_set(pb, SLAPI_LDIF2DB_EXCLUDE, db2ldif_exclude);
int32_t task_flags = SLAPI_TASK_RUNNING_FROM_COMMANDLINE;
slapi_pblock_set(pb, SLAPI_TASK_FLAGS, &task_flags);
- main_setuid(slapdFrontendConfig->localuser);
if ( plugin->plg_ldif2db != NULL ) {
return_value = (*plugin->plg_ldif2db)( pb );
} else {
@@ -2173,9 +2228,6 @@ slapd_exemode_db2ldif(int argc, char** argv)
}
}
- /* [622984] db2lidf -r changes database file ownership
- * should call setuid before "db2ldif_dump_replica" */
- main_setuid(slapdFrontendConfig->localuser);
for (instp = cmd_line_instance_names; instp && *instp; instp++) {
int release_me = 0;
@@ -2421,7 +2473,6 @@ static int slapd_exemode_db2index(void)
slapi_pblock_set(pb, SLAPI_BACKEND_INSTANCE_NAME, cmd_line_instance_name);
int32_t task_flags = SLAPI_TASK_RUNNING_FROM_COMMANDLINE;
slapi_pblock_set(pb, SLAPI_TASK_FLAGS, &task_flags);
- main_setuid(slapdFrontendConfig->localuser);
return_value = (*plugin->plg_db2index)( pb );
slapi_pblock_destroy(pb);
@@ -2472,7 +2523,6 @@ slapd_exemode_db2archive(void)
slapi_pblock_set(pb, SLAPI_SEQ_VAL, archive_name);
int32_t task_flags = SLAPI_TASK_RUNNING_FROM_COMMANDLINE;
slapi_pblock_set(pb, SLAPI_TASK_FLAGS, &task_flags);
- main_setuid(slapdFrontendConfig->localuser);
return_value = (backend_plugin->plg_db2archive)( pb );
slapi_pblock_destroy(pb);
return return_value;
@@ -2521,7 +2571,6 @@ slapd_exemode_archive2db(void)
int32_t task_flags = SLAPI_TASK_RUNNING_FROM_COMMANDLINE;
slapi_pblock_set(pb, SLAPI_TASK_FLAGS, &task_flags);
slapi_pblock_set(pb, SLAPI_BACKEND_INSTANCE_NAME, cmd_line_instance_name);
- main_setuid(slapdFrontendConfig->localuser);
return_value = (backend_plugin->plg_archive2db)( pb );
slapi_pblock_destroy(pb);
return return_value;
@@ -2582,7 +2631,6 @@ slapd_exemode_upgradedb(void)
/* borrowing import code, so need to set up the import variables */
slapi_pblock_set(pb, SLAPI_LDIF2DB_GENERATE_UNIQUEID,
&ldif2db_generate_uniqueid);
slapi_pblock_set(pb, SLAPI_LDIF2DB_NAMESPACEID, &ldif2db_namespaceid);
- main_setuid(slapdFrontendConfig->localuser);
if ( backend_plugin->plg_upgradedb != NULL ) {
return_value = (*backend_plugin->plg_upgradedb)( pb );
} else {
@@ -2657,7 +2705,6 @@ slapd_exemode_upgradednformat(void)
/* borrowing import code, so need to set up the import variables */
slapi_pblock_set(pb, SLAPI_LDIF2DB_GENERATE_UNIQUEID,
&ldif2db_generate_uniqueid);
slapi_pblock_set(pb, SLAPI_LDIF2DB_NAMESPACEID, &ldif2db_namespaceid);
- main_setuid(slapdFrontendConfig->localuser);
if ( backend_plugin->plg_upgradednformat != NULL ) {
rc = (*backend_plugin->plg_upgradednformat)( pb );
} else {
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index 9696ead..0439915 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -575,10 +575,8 @@ int config_set_dynamic_plugins(const char *attrname, char *value,
char *errorbuf
int config_get_dynamic_plugins(void);
int config_set_cn_uses_dn_syntax_in_dns(const char *attrname, char *value, char
*errorbuf, int apply);
int config_get_cn_uses_dn_syntax_in_dns(void);
-#ifdef ENABLE_NUNC_STANS
int config_get_enable_nunc_stans(void);
int config_set_enable_nunc_stans(const char *attrname, char *value, char *errorbuf, int
apply);
-#endif
int config_set_extract_pem(const char *attrname, char *value, char *errorbuf, int
apply);
PLHashNumber hashNocaseString(const void *key);
@@ -1495,9 +1493,7 @@ void slapd_do_nothing(int);
#endif
void slapd_wait4child (int);
-#ifdef ENABLE_NUNC_STANS
void ns_handle_pr_read_ready(struct ns_job_t *job);
-#endif
void ns_connection_post_io_or_closing(Connection *conn);
/*
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index 2f84d27..2064d4a 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -118,9 +118,7 @@ typedef struct symbol_t {
*/
#include <pwd.h>
-#ifdef ENABLE_NUNC_STANS
#include <nunc-stans.h>
-#endif
#ifdef WITH_SYSTEMD
#ifdef HAVE_JOURNALD
@@ -1619,11 +1617,9 @@ typedef struct conn {
Conn_IO_Layer_cb c_push_io_layer_cb; /* callback to push an IO layer on the
conn->c_prfd */
Conn_IO_Layer_cb c_pop_io_layer_cb; /* callback to pop an IO layer off of the
conn->c_prfd */
void *c_io_layer_cb_data; /* callback data */
-#ifdef ENABLE_NUNC_STANS
struct connection_table *c_ct; /* connection table that this connection belongs
to */
ns_thrpool_t *c_tp; /* thread pool for this connection */
int c_ns_close_jobs; /* number of current close jobs */
-#endif
} Connection;
#define CONN_FLAG_SSL 1 /* Is this connection an SSL connection or not ?
* Used to direct I/O code when SSL is handled differently
@@ -2102,9 +2098,7 @@ typedef struct _slapdEntryPoints {
#define CONFIG_PLUGIN_BINDDN_TRACKING_ATTRIBUTE
"nsslapd-plugin-binddn-tracking"
#define CONFIG_MODDN_ACI_ATTRIBUTE "nsslapd-moddn-aci"
#define CONFIG_GLOBAL_BACKEND_LOCK "nsslapd-global-backend-lock"
-#ifdef ENABLE_NUNC_STANS
#define CONFIG_ENABLE_NUNC_STANS "nsslapd-enable-nunc-stans"
-#endif
#define CONFIG_CONFIG_ATTRIBUTE "nsslapd-config"
#define CONFIG_INSTDIR_ATTRIBUTE "nsslapd-instancedir"
#define CONFIG_SCHEMADIR_ATTRIBUTE "nsslapd-schemadir"
@@ -2445,9 +2439,7 @@ typedef struct _slapdFrontendConfig {
slapi_onoff_t cn_uses_dn_syntax_in_dns; /* indicates the cn value in dns has dn syntax
*/
slapi_onoff_t global_backend_lock;
slapi_int_t maxsimplepaged_per_conn;/* max simple paged results reqs handled per
connection */
-#ifdef ENABLE_NUNC_STANS
slapi_onoff_t enable_nunc_stans;
-#endif
#if defined(LINUX)
int malloc_mxfast; /* mallopt M_MXFAST */
int malloc_trim_threshold; /* mallopt M_TRIM_THRESHOLD */
diff --git a/src/nunc-stans/ns/ns_thrpool.c b/src/nunc-stans/ns/ns_thrpool.c
index 41f5342..435aeb9 100644
--- a/src/nunc-stans/ns/ns_thrpool.c
+++ b/src/nunc-stans/ns/ns_thrpool.c
@@ -841,10 +841,12 @@ ns_add_io_job(ns_thrpool_t *tp, PRFileDesc *fd, ns_job_type_t
job_type,
return PR_FAILURE;
}
+ pthread_mutex_lock(_job->monitor);
#ifdef DEBUG
ns_log(LOG_DEBUG, "ns_add_io_job state %d moving to NS_JOB_ARMED\n",
(_job)->state);
#endif
_job->state = NS_JOB_NEEDS_ARM;
+ pthread_mutex_unlock(_job->monitor);
internal_ns_job_rearm(_job);
/* fill in a pointer to the job for the caller if requested */
@@ -880,10 +882,12 @@ ns_add_timeout_job(ns_thrpool_t *tp, struct timeval *tv,
ns_job_type_t job_type,
return PR_FAILURE;
}
+ pthread_mutex_lock(_job->monitor);
#ifdef DEBUG
ns_log(LOG_DEBUG, "ns_add_timeout_job state %d moving to NS_JOB_ARMED\n",
(_job)->state);
#endif
_job->state = NS_JOB_NEEDS_ARM;
+ pthread_mutex_unlock(_job->monitor);
internal_ns_job_rearm(_job);
/* fill in a pointer to the job for the caller if requested */
@@ -934,12 +938,14 @@ ns_add_io_timeout_job(ns_thrpool_t *tp, PRFileDesc *fd, struct
timeval *tv,
if (!_job) {
return PR_FAILURE;
}
+ pthread_mutex_lock(_job->monitor);
_job->tv = *tv;
#ifdef DEBUG
ns_log(LOG_DEBUG, "ns_add_io_timeout_job state %d moving to
NS_JOB_ARMED\n", (_job)->state);
#endif
_job->state = NS_JOB_NEEDS_ARM;
+ pthread_mutex_unlock(_job->monitor);
internal_ns_job_rearm(_job);
/* fill in a pointer to the job for the caller if requested */
@@ -971,10 +977,12 @@ ns_add_signal_job(ns_thrpool_t *tp, PRInt32 signum, ns_job_type_t
job_type,
return PR_FAILURE;
}
+ pthread_mutex_lock(_job->monitor);
#ifdef DEBUG
ns_log(LOG_DEBUG, "ns_add_signal_job state %d moving to NS_JOB_ARMED\n",
(_job)->state);
#endif
_job->state = NS_JOB_NEEDS_ARM;
+ pthread_mutex_unlock(_job->monitor);
internal_ns_job_rearm(_job);
/* fill in a pointer to the job for the caller if requested */
@@ -1024,7 +1032,9 @@ ns_add_shutdown_job(ns_thrpool_t *tp) {
if (!_job) {
return PR_FAILURE;
}
+ pthread_mutex_lock(_job->monitor);
_job->state = NS_JOB_NEEDS_ARM;
+ pthread_mutex_unlock(_job->monitor);
internal_ns_job_rearm(_job);
return PR_SUCCESS;
}
@@ -1533,7 +1543,10 @@ ns_thrpool_shutdown(struct ns_thrpool_t *tp)
PRStatus result = ns_add_shutdown_job(tp);
PR_ASSERT(result == PR_SUCCESS);
}
-
+ /* Make sure all threads are woken up to their shutdown jobs. */
+ pthread_mutex_lock(&(tp->work_q_lock));
+ pthread_cond_broadcast(&(tp->work_q_cv));
+ pthread_mutex_unlock(&(tp->work_q_lock));
}
PRStatus
@@ -1547,12 +1560,6 @@ ns_thrpool_wait(ns_thrpool_t *tp)
while (sds_queue_dequeue(tp->thread_stack, (void **)&thr) == SDS_SUCCESS)
{
-
- /* Make sure all threads are woken up to their shutdown jobs. */
- pthread_mutex_lock(&(tp->work_q_lock));
- pthread_cond_broadcast(&(tp->work_q_cv));
- pthread_mutex_unlock(&(tp->work_q_lock));
-
/* void *thread_retval = NULL; */
int32_t rc = pthread_join(thr->thr, NULL);
#ifdef DEBUG
diff --git a/src/nunc-stans/test/test_nuncstans.c b/src/nunc-stans/test/test_nuncstans.c
index 2795302..74ce57d 100644
--- a/src/nunc-stans/test/test_nuncstans.c
+++ b/src/nunc-stans/test/test_nuncstans.c
@@ -402,6 +402,74 @@ ns_job_neg_timeout_test(void **state)
}
+/*
+ * Test that a timeout job fires a within a time window
+ */
+
+static void
+ns_timer_job_cb(struct ns_job_t *job)
+{
+ cb_check += 1;
+ ns_job_done(job);
+ PR_Lock(cb_lock);
+ PR_NotifyCondVar(cb_cond);
+ /* Disarm ourselves */
+ PR_Unlock(cb_lock);
+}
+
+static void
+ns_job_timer_test(void **state)
+{
+ struct ns_thrpool_t *tp = *state;
+ struct ns_job_t *job = NULL;
+ struct timeval tv = { 2, 0 };
+
+ PR_Lock(cb_lock);
+ assert_true(ns_add_timeout_job(tp, &tv, NS_JOB_THREAD, ns_timer_job_cb, NULL,
&job) == PR_SUCCESS);
+
+ PR_WaitCondVar(cb_cond, PR_SecondsToInterval(1));
+ assert_int_equal(cb_check, 0);
+
+ PR_WaitCondVar(cb_cond, PR_SecondsToInterval(2));
+ PR_Unlock(cb_lock);
+ assert_int_equal(cb_check, 1);
+
+}
+
+/*
+ * Test that within a window, a looping timeout job has fired greater than X times.
+ */
+
+static void
+ns_timer_persist_job_cb(struct ns_job_t *job)
+{
+ cb_check += 1;
+ if (cb_check < 10) {
+ ns_job_rearm(job);
+ } else {
+ ns_job_done(job);
+ }
+}
+
+static void
+ns_job_timer_persist_test(void **state)
+{
+ struct ns_thrpool_t *tp = *state;
+ struct ns_job_t *job = NULL;
+ struct timeval tv = { 1, 0 };
+
+ PR_Lock(cb_lock);
+ assert_true(ns_add_timeout_job(tp, &tv, NS_JOB_THREAD, ns_timer_persist_job_cb,
NULL, &job) == PR_SUCCESS);
+
+ PR_Sleep(PR_SecondsToInterval(5));
+
+ assert_true(cb_check <= 6);
+
+ PR_Sleep(PR_SecondsToInterval(6));
+
+ assert_int_equal(cb_check, 10);
+}
+
int
main(void)
{
@@ -430,6 +498,12 @@ main(void)
cmocka_unit_test_setup_teardown(ns_job_neg_timeout_test,
ns_test_setup,
ns_test_teardown),
+ cmocka_unit_test_setup_teardown(ns_job_timer_test,
+ ns_test_setup,
+ ns_test_teardown),
+ cmocka_unit_test_setup_teardown(ns_job_timer_persist_test,
+ ns_test_setup,
+ ns_test_teardown),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.