|
|
96373c |
From 04605da5c813ffc818d874ae0a14790c166d792d Mon Sep 17 00:00:00 2001
|
|
|
96373c |
From: William Brown <firstyear@redhat.com>
|
|
|
96373c |
Date: Mon, 6 Nov 2017 08:56:01 +1000
|
|
|
96373c |
Subject: [PATCH] Ticket 49435 - Fix NS race condition on loaded test systems
|
|
|
96373c |
|
|
|
96373c |
Bug Description: During a test run, on a heavily loaded systems
|
|
|
96373c |
some events would time out before they could occur correctly.
|
|
|
96373c |
|
|
|
96373c |
Fix Description: Change the structure of events to mitigate
|
|
|
96373c |
a deref performance hit, and add a ns_job_wait conditional
|
|
|
96373c |
that allows blocking on a job to complete so that tests do not
|
|
|
96373c |
require time based checks.
|
|
|
96373c |
|
|
|
96373c |
https://pagure.io/389-ds-base/issue/49435
|
|
|
96373c |
|
|
|
96373c |
Author: wibrown
|
|
|
96373c |
|
|
|
96373c |
Review by: mreynolds (Thanks!)
|
|
|
96373c |
---
|
|
|
96373c |
src/nunc-stans/include/nunc-stans.h | 12 +++
|
|
|
96373c |
src/nunc-stans/ns/ns_event_fw.h | 3 +-
|
|
|
96373c |
src/nunc-stans/ns/ns_thrpool.c | 175 +++++++++++++++++++++--------------
|
|
|
96373c |
src/nunc-stans/test/test_nuncstans.c | 156 ++++++++++++++++++-------------
|
|
|
96373c |
4 files changed, 209 insertions(+), 137 deletions(-)
|
|
|
96373c |
|
|
|
96373c |
diff --git a/src/nunc-stans/include/nunc-stans.h b/src/nunc-stans/include/nunc-stans.h
|
|
|
96373c |
index 386a8d283..192e38ec3 100644
|
|
|
96373c |
--- a/src/nunc-stans/include/nunc-stans.h
|
|
|
96373c |
+++ b/src/nunc-stans/include/nunc-stans.h
|
|
|
96373c |
@@ -77,6 +77,10 @@ typedef enum _ns_result_t {
|
|
|
96373c |
* This occurs when a lower level OS issue occurs, generally thread related.
|
|
|
96373c |
*/
|
|
|
96373c |
NS_THREAD_FAILURE = 5,
|
|
|
96373c |
+ /**
|
|
|
96373c |
+ * The job is being deleted
|
|
|
96373c |
+ */
|
|
|
96373c |
+ NS_DELETING = 6,
|
|
|
96373c |
} ns_result_t;
|
|
|
96373c |
|
|
|
96373c |
/**
|
|
|
96373c |
@@ -837,6 +841,14 @@ ns_job_type_t ns_job_get_output_type(struct ns_job_t *job);
|
|
|
96373c |
ns_result_t ns_job_set_done_cb(struct ns_job_t *job, ns_job_func_t func);
|
|
|
96373c |
|
|
|
96373c |
/**
|
|
|
96373c |
+ * Block until a job is completed. This returns the next state of the job as as a return.
|
|
|
96373c |
+ *
|
|
|
96373c |
+ * \param job The job to set the callback for.
|
|
|
96373c |
+ * \retval ns_job_state_t The next state the job will move to. IE, WAITING, DELETED, ARMED.
|
|
|
96373c |
+ */
|
|
|
96373c |
+ns_result_t ns_job_wait(struct ns_job_t *job);
|
|
|
96373c |
+
|
|
|
96373c |
+/**
|
|
|
96373c |
* Creates a new thread pool
|
|
|
96373c |
*
|
|
|
96373c |
* Must be called with a struct ns_thrpool_config that has been
|
|
|
96373c |
diff --git a/src/nunc-stans/ns/ns_event_fw.h b/src/nunc-stans/ns/ns_event_fw.h
|
|
|
96373c |
index 436b28269..88997b24d 100644
|
|
|
96373c |
--- a/src/nunc-stans/ns/ns_event_fw.h
|
|
|
96373c |
+++ b/src/nunc-stans/ns/ns_event_fw.h
|
|
|
96373c |
@@ -80,7 +80,8 @@ typedef enum _ns_job_state {
|
|
|
96373c |
interface between the app/thread pool/event framework */
|
|
|
96373c |
typedef struct ns_job_t
|
|
|
96373c |
{
|
|
|
96373c |
- pthread_mutex_t *monitor;
|
|
|
96373c |
+ pthread_mutex_t monitor;
|
|
|
96373c |
+ pthread_cond_t notify;
|
|
|
96373c |
struct ns_thrpool_t *tp;
|
|
|
96373c |
ns_job_func_t func;
|
|
|
96373c |
struct ns_job_data_t *data;
|
|
|
96373c |
diff --git a/src/nunc-stans/ns/ns_thrpool.c b/src/nunc-stans/ns/ns_thrpool.c
|
|
|
96373c |
index 2ad0bd799..1d8bb03f1 100644
|
|
|
96373c |
--- a/src/nunc-stans/ns/ns_thrpool.c
|
|
|
96373c |
+++ b/src/nunc-stans/ns/ns_thrpool.c
|
|
|
96373c |
@@ -214,7 +214,7 @@ job_queue_cleanup(void *arg)
|
|
|
96373c |
static void
|
|
|
96373c |
internal_ns_job_done(ns_job_t *job)
|
|
|
96373c |
{
|
|
|
96373c |
- pthread_mutex_lock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_lock(&(job->monitor));
|
|
|
96373c |
#ifdef DEBUG
|
|
|
96373c |
ns_log(LOG_DEBUG, "internal_ns_job_done %x state %d moving to NS_JOB_DELETED\n", job, job->state);
|
|
|
96373c |
#endif
|
|
|
96373c |
@@ -239,9 +239,9 @@ internal_ns_job_done(ns_job_t *job)
|
|
|
96373c |
job->done_cb(job);
|
|
|
96373c |
}
|
|
|
96373c |
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
- pthread_mutex_destroy(job->monitor);
|
|
|
96373c |
- ns_free(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
+ pthread_mutex_destroy(&(job->monitor));
|
|
|
96373c |
+ pthread_cond_destroy(&(job->notify));
|
|
|
96373c |
|
|
|
96373c |
ns_free(job);
|
|
|
96373c |
}
|
|
|
96373c |
@@ -250,7 +250,7 @@ internal_ns_job_done(ns_job_t *job)
|
|
|
96373c |
static void
|
|
|
96373c |
internal_ns_job_rearm(ns_job_t *job)
|
|
|
96373c |
{
|
|
|
96373c |
- pthread_mutex_lock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_lock(&(job->monitor));
|
|
|
96373c |
PR_ASSERT(job->state == NS_JOB_NEEDS_ARM);
|
|
|
96373c |
/* Don't think I need to check persistence here, it could be the first arm ... */
|
|
|
96373c |
#ifdef DEBUG
|
|
|
96373c |
@@ -267,7 +267,7 @@ internal_ns_job_rearm(ns_job_t *job)
|
|
|
96373c |
/* Prevents an un-necessary queue / dequeue to the event_q */
|
|
|
96373c |
work_q_notify(job);
|
|
|
96373c |
}
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
}
|
|
|
96373c |
|
|
|
96373c |
static void
|
|
|
96373c |
@@ -281,7 +281,7 @@ work_job_execute(ns_job_t *job)
|
|
|
96373c |
* DELETED! Crashes abound, you have been warned ...
|
|
|
96373c |
*/
|
|
|
96373c |
PR_ASSERT(job);
|
|
|
96373c |
- pthread_mutex_lock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_lock(&(job->monitor));
|
|
|
96373c |
#ifdef DEBUG
|
|
|
96373c |
ns_log(LOG_DEBUG, "work_job_execute %x state %d moving to NS_JOB_RUNNING\n", job, job->state);
|
|
|
96373c |
#endif
|
|
|
96373c |
@@ -303,7 +303,12 @@ work_job_execute(ns_job_t *job)
|
|
|
96373c |
#ifdef DEBUG
|
|
|
96373c |
ns_log(LOG_DEBUG, "work_job_execute %x state %d job func complete, sending to job_done...\n", job, job->state);
|
|
|
96373c |
#endif
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ /*
|
|
|
96373c |
+ * Let waiters know we are done, they'll pick up once
|
|
|
96373c |
+ * we unlock.
|
|
|
96373c |
+ */
|
|
|
96373c |
+ pthread_cond_signal(&(job->notify));
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
internal_ns_job_done(job);
|
|
|
96373c |
/* MUST NOT ACCESS JOB AGAIN.*/
|
|
|
96373c |
} else if (job->state == NS_JOB_NEEDS_ARM) {
|
|
|
96373c |
@@ -311,7 +316,8 @@ work_job_execute(ns_job_t *job)
|
|
|
96373c |
ns_log(LOG_DEBUG, "work_job_execute %x state %d job func complete, sending to rearm...\n", job, job->state);
|
|
|
96373c |
#endif
|
|
|
96373c |
/* Rearm the job! */
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ /* We *don't* notify here because we ARE NOT done! */
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
internal_ns_job_rearm(job);
|
|
|
96373c |
} else {
|
|
|
96373c |
#ifdef DEBUG
|
|
|
96373c |
@@ -321,7 +327,12 @@ work_job_execute(ns_job_t *job)
|
|
|
96373c |
PR_ASSERT(!NS_JOB_IS_PERSIST(job->job_type));
|
|
|
96373c |
/* We are now idle, set waiting. */
|
|
|
96373c |
job->state = NS_JOB_WAITING;
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ /*
|
|
|
96373c |
+ * Let waiters know we are done, they'll pick up once
|
|
|
96373c |
+ * we unlock.
|
|
|
96373c |
+ */
|
|
|
96373c |
+ pthread_cond_signal(&(job->notify));
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
}
|
|
|
96373c |
/* MUST NOT ACCESS JOB AGAIN */
|
|
|
96373c |
}
|
|
|
96373c |
@@ -338,7 +349,7 @@ static void
|
|
|
96373c |
work_q_notify(ns_job_t *job)
|
|
|
96373c |
{
|
|
|
96373c |
PR_ASSERT(job);
|
|
|
96373c |
- pthread_mutex_lock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_lock(&(job->monitor));
|
|
|
96373c |
#ifdef DEBUG
|
|
|
96373c |
ns_log(LOG_DEBUG, "work_q_notify %x state %d\n", job, job->state);
|
|
|
96373c |
#endif
|
|
|
96373c |
@@ -346,12 +357,12 @@ work_q_notify(ns_job_t *job)
|
|
|
96373c |
if (job->state != NS_JOB_ARMED) {
|
|
|
96373c |
/* Maybe we should return some error here? */
|
|
|
96373c |
ns_log(LOG_ERR, "work_q_notify %x state %d is not ARMED, cannot queue!\n", job, job->state);
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
return;
|
|
|
96373c |
}
|
|
|
96373c |
/* MUST NOT ACCESS job after enqueue. So we stash tp.*/
|
|
|
96373c |
ns_thrpool_t *ltp = job->tp;
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
sds_lqueue_enqueue(ltp->work_q, (void *)job);
|
|
|
96373c |
pthread_mutex_lock(&(ltp->work_q_lock));
|
|
|
96373c |
pthread_cond_signal(&(ltp->work_q_cv));
|
|
|
96373c |
@@ -411,13 +422,13 @@ static void
|
|
|
96373c |
update_event(ns_job_t *job)
|
|
|
96373c |
{
|
|
|
96373c |
PR_ASSERT(job);
|
|
|
96373c |
- pthread_mutex_lock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_lock(&(job->monitor));
|
|
|
96373c |
#ifdef DEBUG
|
|
|
96373c |
ns_log(LOG_DEBUG, "update_event %x state %d\n", job, job->state);
|
|
|
96373c |
#endif
|
|
|
96373c |
PR_ASSERT(job->state == NS_JOB_NEEDS_DELETE || job->state == NS_JOB_ARMED);
|
|
|
96373c |
if (job->state == NS_JOB_NEEDS_DELETE) {
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
internal_ns_job_done(job);
|
|
|
96373c |
return;
|
|
|
96373c |
} else if (NS_JOB_IS_IO(job->job_type) || job->ns_event_fw_fd) {
|
|
|
96373c |
@@ -426,7 +437,7 @@ update_event(ns_job_t *job)
|
|
|
96373c |
} else {
|
|
|
96373c |
job->tp->ns_event_fw->ns_event_fw_mod_io(job->tp->ns_event_fw_ctx, job);
|
|
|
96373c |
}
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
/* We need these returns to prevent a race on the next else if condition when we release job->monitor */
|
|
|
96373c |
return;
|
|
|
96373c |
} else if (NS_JOB_IS_TIMER(job->job_type) || job->ns_event_fw_time) {
|
|
|
96373c |
@@ -435,7 +446,7 @@ update_event(ns_job_t *job)
|
|
|
96373c |
} else {
|
|
|
96373c |
job->tp->ns_event_fw->ns_event_fw_mod_timer(job->tp->ns_event_fw_ctx, job);
|
|
|
96373c |
}
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
return;
|
|
|
96373c |
} else if (NS_JOB_IS_SIGNAL(job->job_type) || job->ns_event_fw_sig) {
|
|
|
96373c |
if (!job->ns_event_fw_sig) {
|
|
|
96373c |
@@ -443,15 +454,15 @@ update_event(ns_job_t *job)
|
|
|
96373c |
} else {
|
|
|
96373c |
job->tp->ns_event_fw->ns_event_fw_mod_signal(job->tp->ns_event_fw_ctx, job);
|
|
|
96373c |
}
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
return;
|
|
|
96373c |
} else {
|
|
|
96373c |
/* It's a "run now" job. */
|
|
|
96373c |
if (NS_JOB_IS_THREAD(job->job_type)) {
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
work_q_notify(job);
|
|
|
96373c |
} else {
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
event_q_notify(job);
|
|
|
96373c |
}
|
|
|
96373c |
}
|
|
|
96373c |
@@ -602,14 +613,14 @@ event_cb(ns_job_t *job)
|
|
|
96373c |
*/
|
|
|
96373c |
|
|
|
96373c |
/* There is no guarantee this won't be called once we start to enter the shutdown, especially with timers .... */
|
|
|
96373c |
- pthread_mutex_lock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_lock(&(job->monitor));
|
|
|
96373c |
|
|
|
96373c |
PR_ASSERT(job->state == NS_JOB_ARMED || job->state == NS_JOB_NEEDS_DELETE);
|
|
|
96373c |
if (job->state == NS_JOB_ARMED && NS_JOB_IS_THREAD(job->job_type)) {
|
|
|
96373c |
#ifdef DEBUG
|
|
|
96373c |
ns_log(LOG_DEBUG, "event_cb %x state %d threaded, send to work_q\n", job, job->state);
|
|
|
96373c |
#endif
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
work_q_notify(job);
|
|
|
96373c |
} else if (job->state == NS_JOB_NEEDS_DELETE) {
|
|
|
96373c |
#ifdef DEBUG
|
|
|
96373c |
@@ -620,14 +631,14 @@ event_cb(ns_job_t *job)
|
|
|
96373c |
* It's here because it's been QUEUED for deletion and *may* be coming
|
|
|
96373c |
* from the thrpool destroy thread!
|
|
|
96373c |
*/
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
|
|
|
96373c |
} else {
|
|
|
96373c |
#ifdef DEBUG
|
|
|
96373c |
ns_log(LOG_DEBUG, "event_cb %x state %d non-threaded, execute right meow\n", job, job->state);
|
|
|
96373c |
#endif
|
|
|
96373c |
/* Not threaded, execute now! */
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
work_job_execute(job);
|
|
|
96373c |
/* MUST NOT ACCESS JOB FROM THIS POINT */
|
|
|
96373c |
}
|
|
|
96373c |
@@ -682,12 +693,12 @@ static ns_job_t *
|
|
|
96373c |
new_ns_job(ns_thrpool_t *tp, PRFileDesc *fd, ns_job_type_t job_type, ns_job_func_t func, struct ns_job_data_t *data)
|
|
|
96373c |
{
|
|
|
96373c |
ns_job_t *job = ns_calloc(1, sizeof(ns_job_t));
|
|
|
96373c |
- job->monitor = ns_calloc(1, sizeof(pthread_mutex_t));
|
|
|
96373c |
|
|
|
96373c |
pthread_mutexattr_t *monitor_attr = ns_calloc(1, sizeof(pthread_mutexattr_t));
|
|
|
96373c |
pthread_mutexattr_init(monitor_attr);
|
|
|
96373c |
pthread_mutexattr_settype(monitor_attr, PTHREAD_MUTEX_RECURSIVE);
|
|
|
96373c |
- assert(pthread_mutex_init(job->monitor, monitor_attr) == 0);
|
|
|
96373c |
+ assert(pthread_mutex_init(&(job->monitor), monitor_attr) == 0);
|
|
|
96373c |
+ assert(pthread_cond_init(&(job->notify), NULL) == 0);
|
|
|
96373c |
ns_free(monitor_attr);
|
|
|
96373c |
|
|
|
96373c |
job->tp = tp;
|
|
|
96373c |
@@ -746,14 +757,14 @@ ns_job_done(ns_job_t *job)
|
|
|
96373c |
/* Get the shutdown state ONCE at the start, atomically */
|
|
|
96373c |
int32_t shutdown_state = ns_thrpool_is_shutdown(job->tp);
|
|
|
96373c |
|
|
|
96373c |
- pthread_mutex_lock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_lock(&(job->monitor));
|
|
|
96373c |
|
|
|
96373c |
if (job->state == NS_JOB_NEEDS_DELETE || job->state == NS_JOB_DELETED) {
|
|
|
96373c |
/* Just return if the job has been marked for deletion */
|
|
|
96373c |
#ifdef DEBUG
|
|
|
96373c |
ns_log(LOG_DEBUG, "ns_job_done %x tp shutdown -> %x state %d return early\n", job, shutdown_state, job->state);
|
|
|
96373c |
#endif
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
return NS_SUCCESS;
|
|
|
96373c |
}
|
|
|
96373c |
|
|
|
96373c |
@@ -762,7 +773,7 @@ ns_job_done(ns_job_t *job)
|
|
|
96373c |
#ifdef DEBUG
|
|
|
96373c |
ns_log(LOG_DEBUG, "ns_job_done %x tp shutdown -> false state %d failed to mark as done\n", job, job->state);
|
|
|
96373c |
#endif
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
return NS_INVALID_STATE;
|
|
|
96373c |
}
|
|
|
96373c |
|
|
|
96373c |
@@ -773,13 +784,13 @@ ns_job_done(ns_job_t *job)
|
|
|
96373c |
ns_log(LOG_DEBUG, "ns_job_done %x tp shutdown -> false state %d setting to async NS_JOB_NEEDS_DELETE\n", job, job->state);
|
|
|
96373c |
#endif
|
|
|
96373c |
job->state = NS_JOB_NEEDS_DELETE;
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
} else if (!shutdown_state) {
|
|
|
96373c |
#ifdef DEBUG
|
|
|
96373c |
ns_log(LOG_DEBUG, "ns_job_done %x tp shutdown -> false state %d setting NS_JOB_NEEDS_DELETE and queuing\n", job, job->state);
|
|
|
96373c |
#endif
|
|
|
96373c |
job->state = NS_JOB_NEEDS_DELETE;
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
event_q_notify(job);
|
|
|
96373c |
} else {
|
|
|
96373c |
#ifdef DEBUG
|
|
|
96373c |
@@ -787,7 +798,7 @@ ns_job_done(ns_job_t *job)
|
|
|
96373c |
#endif
|
|
|
96373c |
job->state = NS_JOB_NEEDS_DELETE;
|
|
|
96373c |
/* We are shutting down, just remove it! */
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
internal_ns_job_done(job);
|
|
|
96373c |
}
|
|
|
96373c |
return NS_SUCCESS;
|
|
|
96373c |
@@ -849,12 +860,12 @@ ns_add_io_job(ns_thrpool_t *tp, PRFileDesc *fd, ns_job_type_t job_type, ns_job_f
|
|
|
96373c |
return NS_ALLOCATION_FAILURE;
|
|
|
96373c |
}
|
|
|
96373c |
|
|
|
96373c |
- pthread_mutex_lock(_job->monitor);
|
|
|
96373c |
+ pthread_mutex_lock(&(_job->monitor));
|
|
|
96373c |
#ifdef DEBUG
|
|
|
96373c |
ns_log(LOG_DEBUG, "ns_add_io_job state %d moving to NS_JOB_ARMED\n", (_job)->state);
|
|
|
96373c |
#endif
|
|
|
96373c |
_job->state = NS_JOB_NEEDS_ARM;
|
|
|
96373c |
- pthread_mutex_unlock(_job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(_job->monitor));
|
|
|
96373c |
internal_ns_job_rearm(_job);
|
|
|
96373c |
|
|
|
96373c |
/* fill in a pointer to the job for the caller if requested */
|
|
|
96373c |
@@ -889,12 +900,12 @@ ns_add_timeout_job(ns_thrpool_t *tp, struct timeval *tv, ns_job_type_t job_type,
|
|
|
96373c |
return NS_ALLOCATION_FAILURE;
|
|
|
96373c |
}
|
|
|
96373c |
|
|
|
96373c |
- pthread_mutex_lock(_job->monitor);
|
|
|
96373c |
+ pthread_mutex_lock(&(_job->monitor));
|
|
|
96373c |
#ifdef DEBUG
|
|
|
96373c |
ns_log(LOG_DEBUG, "ns_add_timeout_job state %d moving to NS_JOB_ARMED\n", (_job)->state);
|
|
|
96373c |
#endif
|
|
|
96373c |
_job->state = NS_JOB_NEEDS_ARM;
|
|
|
96373c |
- pthread_mutex_unlock(_job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(_job->monitor));
|
|
|
96373c |
internal_ns_job_rearm(_job);
|
|
|
96373c |
|
|
|
96373c |
/* fill in a pointer to the job for the caller if requested */
|
|
|
96373c |
@@ -944,14 +955,14 @@ ns_add_io_timeout_job(ns_thrpool_t *tp, PRFileDesc *fd, struct timeval *tv, ns_j
|
|
|
96373c |
if (!_job) {
|
|
|
96373c |
return NS_ALLOCATION_FAILURE;
|
|
|
96373c |
}
|
|
|
96373c |
- pthread_mutex_lock(_job->monitor);
|
|
|
96373c |
+ pthread_mutex_lock(&(_job->monitor));
|
|
|
96373c |
_job->tv = *tv;
|
|
|
96373c |
|
|
|
96373c |
#ifdef DEBUG
|
|
|
96373c |
ns_log(LOG_DEBUG, "ns_add_io_timeout_job state %d moving to NS_JOB_ARMED\n", (_job)->state);
|
|
|
96373c |
#endif
|
|
|
96373c |
_job->state = NS_JOB_NEEDS_ARM;
|
|
|
96373c |
- pthread_mutex_unlock(_job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(_job->monitor));
|
|
|
96373c |
internal_ns_job_rearm(_job);
|
|
|
96373c |
|
|
|
96373c |
/* fill in a pointer to the job for the caller if requested */
|
|
|
96373c |
@@ -982,12 +993,12 @@ ns_add_signal_job(ns_thrpool_t *tp, int32_t signum, ns_job_type_t job_type, ns_j
|
|
|
96373c |
return NS_ALLOCATION_FAILURE;
|
|
|
96373c |
}
|
|
|
96373c |
|
|
|
96373c |
- pthread_mutex_lock(_job->monitor);
|
|
|
96373c |
+ pthread_mutex_lock(&(_job->monitor));
|
|
|
96373c |
#ifdef DEBUG
|
|
|
96373c |
ns_log(LOG_DEBUG, "ns_add_signal_job state %d moving to NS_JOB_ARMED\n", (_job)->state);
|
|
|
96373c |
#endif
|
|
|
96373c |
_job->state = NS_JOB_NEEDS_ARM;
|
|
|
96373c |
- pthread_mutex_unlock(_job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(_job->monitor));
|
|
|
96373c |
internal_ns_job_rearm(_job);
|
|
|
96373c |
|
|
|
96373c |
/* fill in a pointer to the job for the caller if requested */
|
|
|
96373c |
@@ -1038,9 +1049,9 @@ ns_add_shutdown_job(ns_thrpool_t *tp)
|
|
|
96373c |
if (!_job) {
|
|
|
96373c |
return NS_ALLOCATION_FAILURE;
|
|
|
96373c |
}
|
|
|
96373c |
- pthread_mutex_lock(_job->monitor);
|
|
|
96373c |
+ pthread_mutex_lock(&(_job->monitor));
|
|
|
96373c |
_job->state = NS_JOB_NEEDS_ARM;
|
|
|
96373c |
- pthread_mutex_unlock(_job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(_job->monitor));
|
|
|
96373c |
internal_ns_job_rearm(_job);
|
|
|
96373c |
return NS_SUCCESS;
|
|
|
96373c |
}
|
|
|
96373c |
@@ -1061,13 +1072,13 @@ void *
|
|
|
96373c |
ns_job_get_data(ns_job_t *job)
|
|
|
96373c |
{
|
|
|
96373c |
PR_ASSERT(job);
|
|
|
96373c |
- pthread_mutex_lock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_lock(&(job->monitor));
|
|
|
96373c |
PR_ASSERT(job->state != NS_JOB_DELETED);
|
|
|
96373c |
if (job->state != NS_JOB_DELETED) {
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
return job->data;
|
|
|
96373c |
} else {
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
return NULL;
|
|
|
96373c |
}
|
|
|
96373c |
}
|
|
|
96373c |
@@ -1076,14 +1087,14 @@ ns_result_t
|
|
|
96373c |
ns_job_set_data(ns_job_t *job, void *data)
|
|
|
96373c |
{
|
|
|
96373c |
PR_ASSERT(job);
|
|
|
96373c |
- pthread_mutex_lock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_lock(&(job->monitor));
|
|
|
96373c |
PR_ASSERT(job->state == NS_JOB_WAITING || job->state == NS_JOB_RUNNING);
|
|
|
96373c |
if (job->state == NS_JOB_WAITING || job->state == NS_JOB_RUNNING) {
|
|
|
96373c |
job->data = data;
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
return NS_SUCCESS;
|
|
|
96373c |
} else {
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
return NS_INVALID_STATE;
|
|
|
96373c |
}
|
|
|
96373c |
}
|
|
|
96373c |
@@ -1092,13 +1103,13 @@ ns_thrpool_t *
|
|
|
96373c |
ns_job_get_tp(ns_job_t *job)
|
|
|
96373c |
{
|
|
|
96373c |
PR_ASSERT(job);
|
|
|
96373c |
- pthread_mutex_lock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_lock(&(job->monitor));
|
|
|
96373c |
PR_ASSERT(job->state != NS_JOB_DELETED);
|
|
|
96373c |
if (job->state != NS_JOB_DELETED) {
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
return job->tp;
|
|
|
96373c |
} else {
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
return NULL;
|
|
|
96373c |
}
|
|
|
96373c |
}
|
|
|
96373c |
@@ -1107,13 +1118,13 @@ ns_job_type_t
|
|
|
96373c |
ns_job_get_output_type(ns_job_t *job)
|
|
|
96373c |
{
|
|
|
96373c |
PR_ASSERT(job);
|
|
|
96373c |
- pthread_mutex_lock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_lock(&(job->monitor));
|
|
|
96373c |
PR_ASSERT(job->state == NS_JOB_RUNNING);
|
|
|
96373c |
if (job->state == NS_JOB_RUNNING) {
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
return job->output_job_type;
|
|
|
96373c |
} else {
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
return 0;
|
|
|
96373c |
}
|
|
|
96373c |
}
|
|
|
96373c |
@@ -1122,13 +1133,13 @@ ns_job_type_t
|
|
|
96373c |
ns_job_get_type(ns_job_t *job)
|
|
|
96373c |
{
|
|
|
96373c |
PR_ASSERT(job);
|
|
|
96373c |
- pthread_mutex_lock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_lock(&(job->monitor));
|
|
|
96373c |
PR_ASSERT(job->state != NS_JOB_DELETED);
|
|
|
96373c |
if (job->state != NS_JOB_DELETED) {
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
return job->job_type;
|
|
|
96373c |
} else {
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
return 0;
|
|
|
96373c |
}
|
|
|
96373c |
}
|
|
|
96373c |
@@ -1137,13 +1148,13 @@ PRFileDesc *
|
|
|
96373c |
ns_job_get_fd(ns_job_t *job)
|
|
|
96373c |
{
|
|
|
96373c |
PR_ASSERT(job);
|
|
|
96373c |
- pthread_mutex_lock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_lock(&(job->monitor));
|
|
|
96373c |
PR_ASSERT(job->state != NS_JOB_DELETED);
|
|
|
96373c |
if (job->state != NS_JOB_DELETED) {
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
return job->fd;
|
|
|
96373c |
} else {
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
return NULL;
|
|
|
96373c |
}
|
|
|
96373c |
}
|
|
|
96373c |
@@ -1152,18 +1163,40 @@ ns_result_t
|
|
|
96373c |
ns_job_set_done_cb(struct ns_job_t *job, ns_job_func_t func)
|
|
|
96373c |
{
|
|
|
96373c |
PR_ASSERT(job);
|
|
|
96373c |
- pthread_mutex_lock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_lock(&(job->monitor));
|
|
|
96373c |
PR_ASSERT(job->state == NS_JOB_WAITING || job->state == NS_JOB_RUNNING);
|
|
|
96373c |
if (job->state == NS_JOB_WAITING || job->state == NS_JOB_RUNNING) {
|
|
|
96373c |
job->done_cb = func;
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
return NS_SUCCESS;
|
|
|
96373c |
} else {
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
return NS_INVALID_STATE;
|
|
|
96373c |
}
|
|
|
96373c |
}
|
|
|
96373c |
|
|
|
96373c |
+ns_result_t
|
|
|
96373c |
+ns_job_wait(struct ns_job_t *job) {
|
|
|
96373c |
+ PR_ASSERT(job);
|
|
|
96373c |
+ pthread_mutex_lock(&(job->monitor));
|
|
|
96373c |
+ if (job->state == NS_JOB_WAITING) {
|
|
|
96373c |
+ /* It's done */
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
+ return NS_SUCCESS;
|
|
|
96373c |
+ } else {
|
|
|
96373c |
+ pthread_cond_wait(&(job->notify), &(job->monitor));
|
|
|
96373c |
+ ns_job_state_t result = job->state;
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
+ if (result == NS_JOB_WAITING) {
|
|
|
96373c |
+ return NS_SUCCESS;
|
|
|
96373c |
+ } else if (result == NS_JOB_NEEDS_DELETE) {
|
|
|
96373c |
+ return NS_DELETING;
|
|
|
96373c |
+ } else {
|
|
|
96373c |
+ PR_ASSERT(1 == 0);
|
|
|
96373c |
+ return NS_INVALID_STATE;
|
|
|
96373c |
+ }
|
|
|
96373c |
+ }
|
|
|
96373c |
+}
|
|
|
96373c |
|
|
|
96373c |
/*
|
|
|
96373c |
* This is a convenience function - use if you need to re-arm the same event
|
|
|
96373c |
@@ -1173,7 +1206,7 @@ ns_result_t
|
|
|
96373c |
ns_job_rearm(ns_job_t *job)
|
|
|
96373c |
{
|
|
|
96373c |
PR_ASSERT(job);
|
|
|
96373c |
- pthread_mutex_lock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_lock(&(job->monitor));
|
|
|
96373c |
PR_ASSERT(job->state == NS_JOB_WAITING || job->state == NS_JOB_RUNNING);
|
|
|
96373c |
|
|
|
96373c |
if (ns_thrpool_is_shutdown(job->tp)) {
|
|
|
96373c |
@@ -1186,7 +1219,7 @@ ns_job_rearm(ns_job_t *job)
|
|
|
96373c |
#endif
|
|
|
96373c |
job->state = NS_JOB_NEEDS_ARM;
|
|
|
96373c |
internal_ns_job_rearm(job);
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
return NS_SUCCESS;
|
|
|
96373c |
} else if (!NS_JOB_IS_PERSIST(job->job_type) && job->state == NS_JOB_RUNNING) {
|
|
|
96373c |
/* For this to be called, and NS_JOB_RUNNING, we *must* be the callback thread! */
|
|
|
96373c |
@@ -1195,10 +1228,10 @@ ns_job_rearm(ns_job_t *job)
|
|
|
96373c |
ns_log(LOG_DEBUG, "ns_rearm_job %x state %d setting NS_JOB_NEEDS_ARM\n", job, job->state);
|
|
|
96373c |
#endif
|
|
|
96373c |
job->state = NS_JOB_NEEDS_ARM;
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
return NS_SUCCESS;
|
|
|
96373c |
} else {
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
return NS_INVALID_STATE;
|
|
|
96373c |
}
|
|
|
96373c |
/* Unreachable code .... */
|
|
|
96373c |
@@ -1254,7 +1287,7 @@ setup_event_q_wakeup(ns_thrpool_t *tp)
|
|
|
96373c |
NS_JOB_READ | NS_JOB_PERSIST | NS_JOB_PRESERVE_FD,
|
|
|
96373c |
wakeup_cb, NULL);
|
|
|
96373c |
|
|
|
96373c |
- pthread_mutex_lock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_lock(&(job->monitor));
|
|
|
96373c |
|
|
|
96373c |
/* The event_queue wakeup is ready, arm it. */
|
|
|
96373c |
#ifdef DEBUG
|
|
|
96373c |
@@ -1267,7 +1300,7 @@ setup_event_q_wakeup(ns_thrpool_t *tp)
|
|
|
96373c |
|
|
|
96373c |
/* Stash the wakeup job in tp so we can release it later. */
|
|
|
96373c |
tp->event_q_wakeup_job = job;
|
|
|
96373c |
- pthread_mutex_unlock(job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(job->monitor));
|
|
|
96373c |
}
|
|
|
96373c |
|
|
|
96373c |
/* Initialize the thrpool config */
|
|
|
96373c |
@@ -1463,7 +1496,7 @@ ns_thrpool_destroy(struct ns_thrpool_t *tp)
|
|
|
96373c |
* and use it to wake up the event loop.
|
|
|
96373c |
*/
|
|
|
96373c |
|
|
|
96373c |
- pthread_mutex_lock(tp->event_q_wakeup_job->monitor);
|
|
|
96373c |
+ pthread_mutex_lock(&(tp->event_q_wakeup_job->monitor));
|
|
|
96373c |
|
|
|
96373c |
// tp->event_q_wakeup_job->job_type |= NS_JOB_THREAD;
|
|
|
96373c |
/* This triggers the job to "run", which will cause a shutdown cascade */
|
|
|
96373c |
@@ -1471,7 +1504,7 @@ ns_thrpool_destroy(struct ns_thrpool_t *tp)
|
|
|
96373c |
ns_log(LOG_DEBUG, "ns_thrpool_destroy %x state %d moving to NS_JOB_NEEDS_DELETE\n", tp->event_q_wakeup_job, tp->event_q_wakeup_job->state);
|
|
|
96373c |
#endif
|
|
|
96373c |
tp->event_q_wakeup_job->state = NS_JOB_NEEDS_DELETE;
|
|
|
96373c |
- pthread_mutex_unlock(tp->event_q_wakeup_job->monitor);
|
|
|
96373c |
+ pthread_mutex_unlock(&(tp->event_q_wakeup_job->monitor));
|
|
|
96373c |
/* Has to be event_q_notify, not internal_job_done */
|
|
|
96373c |
event_q_notify(tp->event_q_wakeup_job);
|
|
|
96373c |
|
|
|
96373c |
diff --git a/src/nunc-stans/test/test_nuncstans.c b/src/nunc-stans/test/test_nuncstans.c
|
|
|
96373c |
index 629377a89..afe3c02fc 100644
|
|
|
96373c |
--- a/src/nunc-stans/test/test_nuncstans.c
|
|
|
96373c |
+++ b/src/nunc-stans/test/test_nuncstans.c
|
|
|
96373c |
@@ -55,14 +55,21 @@
|
|
|
96373c |
/* We need the internal headers for state checks */
|
|
|
96373c |
#include "../ns/ns_event_fw.h"
|
|
|
96373c |
|
|
|
96373c |
+#include <assert.h>
|
|
|
96373c |
+
|
|
|
96373c |
+#include <time.h>
|
|
|
96373c |
+
|
|
|
96373c |
#ifdef HAVE_STDLIB_H
|
|
|
96373c |
#include <stdlib.h>
|
|
|
96373c |
#endif
|
|
|
96373c |
|
|
|
96373c |
|
|
|
96373c |
static int cb_check = 0;
|
|
|
96373c |
-static PRLock *cb_lock = NULL;
|
|
|
96373c |
-static PRCondVar *cb_cond = NULL;
|
|
|
96373c |
+
|
|
|
96373c |
+static pthread_mutex_t cb_lock;
|
|
|
96373c |
+static pthread_cond_t cb_cond;
|
|
|
96373c |
+// static PRLock *cb_lock = NULL;
|
|
|
96373c |
+// static PRCondVar *cb_cond = NULL;
|
|
|
96373c |
|
|
|
96373c |
void
|
|
|
96373c |
ns_test_logger(int priority __attribute__((unused)), const char *fmt, va_list varg)
|
|
|
96373c |
@@ -71,6 +78,19 @@ ns_test_logger(int priority __attribute__((unused)), const char *fmt, va_list va
|
|
|
96373c |
vprintf(fmt, varg);
|
|
|
96373c |
}
|
|
|
96373c |
|
|
|
96373c |
+static int
|
|
|
96373c |
+cond_wait_rel(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict reltime) {
|
|
|
96373c |
+ struct timespec now;
|
|
|
96373c |
+ struct timespec abswait;
|
|
|
96373c |
+
|
|
|
96373c |
+ clock_gettime(CLOCK_REALTIME, &now;;
|
|
|
96373c |
+
|
|
|
96373c |
+ abswait.tv_sec = now.tv_sec + reltime->tv_sec;
|
|
|
96373c |
+ abswait.tv_nsec = now.tv_nsec + reltime->tv_nsec;
|
|
|
96373c |
+
|
|
|
96373c |
+ return pthread_cond_timedwait(cond, mutex, &abswait);
|
|
|
96373c |
+}
|
|
|
96373c |
+
|
|
|
96373c |
/* All our other tests will use this in some form. */
|
|
|
96373c |
static int
|
|
|
96373c |
ns_test_setup(void **state)
|
|
|
96373c |
@@ -81,8 +101,8 @@ ns_test_setup(void **state)
|
|
|
96373c |
/* Reset the callback check */
|
|
|
96373c |
cb_check = 0;
|
|
|
96373c |
/* Create the cond var the CB check will use. */
|
|
|
96373c |
- cb_lock = PR_NewLock();
|
|
|
96373c |
- cb_cond = PR_NewCondVar(cb_lock);
|
|
|
96373c |
+ assert(pthread_mutex_init(&cb_lock, NULL) == 0);
|
|
|
96373c |
+ assert(pthread_cond_init(&cb_cond, NULL) == 0);
|
|
|
96373c |
|
|
|
96373c |
ns_thrpool_config_init(&ns_config);
|
|
|
96373c |
|
|
|
96373c |
@@ -105,8 +125,8 @@ ns_test_teardown(void **state)
|
|
|
96373c |
|
|
|
96373c |
ns_thrpool_destroy(tp);
|
|
|
96373c |
|
|
|
96373c |
- PR_DestroyCondVar(cb_cond);
|
|
|
96373c |
- PR_DestroyLock(cb_lock);
|
|
|
96373c |
+ pthread_cond_destroy(&cb_cond);
|
|
|
96373c |
+ pthread_mutex_destroy(&cb_lock);
|
|
|
96373c |
|
|
|
96373c |
return 0;
|
|
|
96373c |
}
|
|
|
96373c |
@@ -114,24 +134,23 @@ ns_test_teardown(void **state)
|
|
|
96373c |
static void
|
|
|
96373c |
ns_init_test_job_cb(struct ns_job_t *job __attribute__((unused)))
|
|
|
96373c |
{
|
|
|
96373c |
+ pthread_mutex_lock(&cb_lock);
|
|
|
96373c |
cb_check += 1;
|
|
|
96373c |
- PR_Lock(cb_lock);
|
|
|
96373c |
- PR_NotifyCondVar(cb_cond);
|
|
|
96373c |
- PR_Unlock(cb_lock);
|
|
|
96373c |
+ pthread_cond_signal(&cb_cond);
|
|
|
96373c |
+ pthread_mutex_unlock(&cb_lock);
|
|
|
96373c |
}
|
|
|
96373c |
|
|
|
96373c |
static void
|
|
|
96373c |
ns_init_disarm_job_cb(struct ns_job_t *job)
|
|
|
96373c |
{
|
|
|
96373c |
if (ns_job_done(job) == NS_SUCCESS) {
|
|
|
96373c |
+ pthread_mutex_lock(&cb_lock);
|
|
|
96373c |
cb_check = 1;
|
|
|
96373c |
+ pthread_cond_signal(&cb_cond);
|
|
|
96373c |
+ pthread_mutex_unlock(&cb_lock);
|
|
|
96373c |
} else {
|
|
|
96373c |
assert_int_equal(1, 0);
|
|
|
96373c |
}
|
|
|
96373c |
- PR_Lock(cb_lock);
|
|
|
96373c |
- PR_NotifyCondVar(cb_cond);
|
|
|
96373c |
- /* Disarm ourselves */
|
|
|
96373c |
- PR_Unlock(cb_lock);
|
|
|
96373c |
}
|
|
|
96373c |
|
|
|
96373c |
static void
|
|
|
96373c |
@@ -146,20 +165,20 @@ ns_init_test(void **state)
|
|
|
96373c |
{
|
|
|
96373c |
struct ns_thrpool_t *tp = *state;
|
|
|
96373c |
struct ns_job_t *job = NULL;
|
|
|
96373c |
+ struct timespec timeout = {1, 0};
|
|
|
96373c |
|
|
|
96373c |
- PR_Lock(cb_lock);
|
|
|
96373c |
+ pthread_mutex_lock(&cb_lock);
|
|
|
96373c |
assert_int_equal(
|
|
|
96373c |
ns_add_job(tp, NS_JOB_NONE | NS_JOB_THREAD, ns_init_test_job_cb, NULL, &job),
|
|
|
96373c |
0);
|
|
|
96373c |
|
|
|
96373c |
- PR_WaitCondVar(cb_cond, PR_SecondsToInterval(1));
|
|
|
96373c |
- PR_Unlock(cb_lock);
|
|
|
96373c |
+ assert(cond_wait_rel(&cb_cond, &cb_lock, &timeout) == 0);
|
|
|
96373c |
+ pthread_mutex_unlock(&cb_lock);
|
|
|
96373c |
|
|
|
96373c |
assert_int_equal(cb_check, 1);
|
|
|
96373c |
|
|
|
96373c |
/* Once the job is done, it's not in the event queue, and it's complete */
|
|
|
96373c |
- /* We have to stall momentarily to let the work_job_execute release the job to us */
|
|
|
96373c |
- PR_Sleep(PR_SecondsToInterval(1));
|
|
|
96373c |
+ assert(ns_job_wait(job) == NS_SUCCESS);
|
|
|
96373c |
assert_int_equal(ns_job_done(job), NS_SUCCESS);
|
|
|
96373c |
}
|
|
|
96373c |
|
|
|
96373c |
@@ -169,19 +188,20 @@ ns_set_data_test(void **state)
|
|
|
96373c |
/* Add a job with data */
|
|
|
96373c |
struct ns_thrpool_t *tp = *state;
|
|
|
96373c |
struct ns_job_t *job = NULL;
|
|
|
96373c |
+ struct timespec timeout = {1, 0};
|
|
|
96373c |
|
|
|
96373c |
char *data = malloc(6);
|
|
|
96373c |
|
|
|
96373c |
strcpy(data, "first");
|
|
|
96373c |
|
|
|
96373c |
- PR_Lock(cb_lock);
|
|
|
96373c |
+ pthread_mutex_lock(&cb_lock);
|
|
|
96373c |
assert_int_equal(
|
|
|
96373c |
ns_add_job(tp, NS_JOB_NONE | NS_JOB_THREAD, ns_init_test_job_cb, data, &job),
|
|
|
96373c |
NS_SUCCESS);
|
|
|
96373c |
|
|
|
96373c |
/* Let the job run */
|
|
|
96373c |
- PR_WaitCondVar(cb_cond, PR_SecondsToInterval(1));
|
|
|
96373c |
- PR_Unlock(cb_lock);
|
|
|
96373c |
+ assert(cond_wait_rel(&cb_cond, &cb_lock, &timeout) == 0);
|
|
|
96373c |
+ pthread_mutex_unlock(&cb_lock);
|
|
|
96373c |
|
|
|
96373c |
/* Check that the data is correct */
|
|
|
96373c |
char *retrieved = (char *)ns_job_get_data(job);
|
|
|
96373c |
@@ -193,16 +213,14 @@ ns_set_data_test(void **state)
|
|
|
96373c |
data = malloc(7);
|
|
|
96373c |
strcpy(data, "second");
|
|
|
96373c |
|
|
|
96373c |
- while (job->state != NS_JOB_WAITING) {
|
|
|
96373c |
- PR_Sleep(PR_MillisecondsToInterval(50));
|
|
|
96373c |
- }
|
|
|
96373c |
+ assert(ns_job_wait(job) == NS_SUCCESS);
|
|
|
96373c |
ns_job_set_data(job, data);
|
|
|
96373c |
|
|
|
96373c |
/* Rearm, and let it run again. */
|
|
|
96373c |
- PR_Lock(cb_lock);
|
|
|
96373c |
+ pthread_mutex_lock(&cb_lock);
|
|
|
96373c |
ns_job_rearm(job);
|
|
|
96373c |
- PR_WaitCondVar(cb_cond, PR_SecondsToInterval(1));
|
|
|
96373c |
- PR_Unlock(cb_lock);
|
|
|
96373c |
+ assert(cond_wait_rel(&cb_cond, &cb_lock, &timeout) == 0);
|
|
|
96373c |
+ pthread_mutex_unlock(&cb_lock);
|
|
|
96373c |
|
|
|
96373c |
/* Make sure it's now what we expect */
|
|
|
96373c |
retrieved = (char *)ns_job_get_data(job);
|
|
|
96373c |
@@ -218,9 +236,7 @@ ns_set_data_test(void **state)
|
|
|
96373c |
* waiting. we might need a load barrier here ...
|
|
|
96373c |
*/
|
|
|
96373c |
|
|
|
96373c |
- while (job->state != NS_JOB_WAITING) {
|
|
|
96373c |
- PR_Sleep(PR_MillisecondsToInterval(50));
|
|
|
96373c |
- }
|
|
|
96373c |
+ assert(ns_job_wait(job) == NS_SUCCESS);
|
|
|
96373c |
|
|
|
96373c |
assert_int_equal(ns_job_done(job), NS_SUCCESS);
|
|
|
96373c |
}
|
|
|
96373c |
@@ -230,8 +246,9 @@ ns_job_done_cb_test(void **state)
|
|
|
96373c |
{
|
|
|
96373c |
struct ns_thrpool_t *tp = *state;
|
|
|
96373c |
struct ns_job_t *job = NULL;
|
|
|
96373c |
+ struct timespec timeout = {1, 0};
|
|
|
96373c |
|
|
|
96373c |
- PR_Lock(cb_lock);
|
|
|
96373c |
+ pthread_mutex_lock(&cb_lock);
|
|
|
96373c |
assert_int_equal(
|
|
|
96373c |
ns_create_job(tp, NS_JOB_NONE | NS_JOB_THREAD, ns_init_do_nothing_cb, &job),
|
|
|
96373c |
NS_SUCCESS);
|
|
|
96373c |
@@ -240,8 +257,8 @@ ns_job_done_cb_test(void **state)
|
|
|
96373c |
/* Remove it */
|
|
|
96373c |
assert_int_equal(ns_job_done(job), NS_SUCCESS);
|
|
|
96373c |
|
|
|
96373c |
- PR_WaitCondVar(cb_cond, PR_SecondsToInterval(1));
|
|
|
96373c |
- PR_Unlock(cb_lock);
|
|
|
96373c |
+ assert(cond_wait_rel(&cb_cond, &cb_lock, &timeout) == 0);
|
|
|
96373c |
+ pthread_mutex_unlock(&cb_lock);
|
|
|
96373c |
|
|
|
96373c |
assert_int_equal(cb_check, 1);
|
|
|
96373c |
}
|
|
|
96373c |
@@ -250,16 +267,15 @@ static void
|
|
|
96373c |
ns_init_rearm_job_cb(struct ns_job_t *job)
|
|
|
96373c |
{
|
|
|
96373c |
if (ns_job_rearm(job) != NS_SUCCESS) {
|
|
|
96373c |
+ pthread_mutex_lock(&cb_lock);
|
|
|
96373c |
cb_check = 1;
|
|
|
96373c |
/* we failed to re-arm as expected, let's go away ... */
|
|
|
96373c |
assert_int_equal(ns_job_done(job), NS_SUCCESS);
|
|
|
96373c |
+ pthread_cond_signal(&cb_cond);
|
|
|
96373c |
+ pthread_mutex_unlock(&cb_lock);
|
|
|
96373c |
} else {
|
|
|
96373c |
assert_int_equal(1, 0);
|
|
|
96373c |
}
|
|
|
96373c |
- PR_Lock(cb_lock);
|
|
|
96373c |
- PR_NotifyCondVar(cb_cond);
|
|
|
96373c |
- /* Disarm ourselves */
|
|
|
96373c |
- PR_Unlock(cb_lock);
|
|
|
96373c |
}
|
|
|
96373c |
|
|
|
96373c |
static void
|
|
|
96373c |
@@ -268,8 +284,9 @@ ns_job_persist_rearm_ignore_test(void **state)
|
|
|
96373c |
/* Test that rearm ignores the persistent job. */
|
|
|
96373c |
struct ns_thrpool_t *tp = *state;
|
|
|
96373c |
struct ns_job_t *job = NULL;
|
|
|
96373c |
+ struct timespec timeout = {1, 0};
|
|
|
96373c |
|
|
|
96373c |
- PR_Lock(cb_lock);
|
|
|
96373c |
+ pthread_mutex_lock(&cb_lock);
|
|
|
96373c |
assert_int_equal(
|
|
|
96373c |
ns_create_job(tp, NS_JOB_NONE | NS_JOB_THREAD | NS_JOB_PERSIST, ns_init_rearm_job_cb, &job),
|
|
|
96373c |
NS_SUCCESS);
|
|
|
96373c |
@@ -281,8 +298,8 @@ ns_job_persist_rearm_ignore_test(void **state)
|
|
|
96373c |
* should see only 1 in the cb_check.
|
|
|
96373c |
*/
|
|
|
96373c |
|
|
|
96373c |
- PR_WaitCondVar(cb_cond, PR_SecondsToInterval(1));
|
|
|
96373c |
- PR_Unlock(cb_lock);
|
|
|
96373c |
+ assert(cond_wait_rel(&cb_cond, &cb_lock, &timeout) == 0);
|
|
|
96373c |
+ pthread_mutex_unlock(&cb_lock);
|
|
|
96373c |
|
|
|
96373c |
/* If we fail to rearm, this is set to 1 Which is what we want. */
|
|
|
96373c |
assert_int_equal(cb_check, 1);
|
|
|
96373c |
@@ -294,6 +311,7 @@ ns_job_persist_disarm_test(void **state)
|
|
|
96373c |
/* Make a persistent job */
|
|
|
96373c |
struct ns_thrpool_t *tp = *state;
|
|
|
96373c |
struct ns_job_t *job = NULL;
|
|
|
96373c |
+ struct timespec timeout = {2, 0};
|
|
|
96373c |
|
|
|
96373c |
assert_int_equal(
|
|
|
96373c |
ns_create_job(tp, NS_JOB_NONE | NS_JOB_PERSIST, ns_init_disarm_job_cb, &job),
|
|
|
96373c |
@@ -302,9 +320,9 @@ ns_job_persist_disarm_test(void **state)
|
|
|
96373c |
assert_int_equal(ns_job_rearm(job), NS_SUCCESS);
|
|
|
96373c |
|
|
|
96373c |
/* In the callback it should disarm */
|
|
|
96373c |
- PR_Lock(cb_lock);
|
|
|
96373c |
- PR_WaitCondVar(cb_cond, PR_SecondsToInterval(1));
|
|
|
96373c |
- PR_Unlock(cb_lock);
|
|
|
96373c |
+ pthread_mutex_lock(&cb_lock);
|
|
|
96373c |
+ assert(cond_wait_rel(&cb_cond, &cb_lock, &timeout) == 0);
|
|
|
96373c |
+ pthread_mutex_unlock(&cb_lock);
|
|
|
96373c |
/* Make sure it did */
|
|
|
96373c |
assert_int_equal(cb_check, 1);
|
|
|
96373c |
}
|
|
|
96373c |
@@ -329,14 +347,13 @@ ns_job_persist_disarm_test(void **state)
|
|
|
96373c |
static void
|
|
|
96373c |
ns_init_race_done_job_cb(struct ns_job_t *job)
|
|
|
96373c |
{
|
|
|
96373c |
- cb_check += 1;
|
|
|
96373c |
ns_job_done(job);
|
|
|
96373c |
/* We need to sleep to let the job race happen */
|
|
|
96373c |
PR_Sleep(PR_SecondsToInterval(2));
|
|
|
96373c |
- PR_Lock(cb_lock);
|
|
|
96373c |
- PR_NotifyCondVar(cb_cond);
|
|
|
96373c |
- /* Disarm ourselves */
|
|
|
96373c |
- PR_Unlock(cb_lock);
|
|
|
96373c |
+ pthread_mutex_lock(&cb_lock);
|
|
|
96373c |
+ cb_check += 1;
|
|
|
96373c |
+ pthread_cond_signal(&cb_cond);
|
|
|
96373c |
+ pthread_mutex_unlock(&cb_lock);
|
|
|
96373c |
}
|
|
|
96373c |
|
|
|
96373c |
static void
|
|
|
96373c |
@@ -344,14 +361,15 @@ ns_job_race_done_test(void **state)
|
|
|
96373c |
{
|
|
|
96373c |
struct ns_thrpool_t *tp = *state;
|
|
|
96373c |
struct ns_job_t *job = NULL;
|
|
|
96373c |
+ struct timespec timeout = {5, 0};
|
|
|
96373c |
|
|
|
96373c |
- PR_Lock(cb_lock);
|
|
|
96373c |
+ pthread_mutex_lock(&cb_lock);
|
|
|
96373c |
assert_int_equal(
|
|
|
96373c |
ns_add_job(tp, NS_JOB_NONE | NS_JOB_THREAD, ns_init_race_done_job_cb, NULL, &job),
|
|
|
96373c |
NS_SUCCESS);
|
|
|
96373c |
|
|
|
96373c |
- PR_WaitCondVar(cb_cond, PR_SecondsToInterval(5));
|
|
|
96373c |
- PR_Unlock(cb_lock);
|
|
|
96373c |
+ assert(cond_wait_rel(&cb_cond, &cb_lock, &timeout) == 0);
|
|
|
96373c |
+ pthread_mutex_unlock(&cb_lock);
|
|
|
96373c |
|
|
|
96373c |
assert_int_equal(cb_check, 1);
|
|
|
96373c |
}
|
|
|
96373c |
@@ -365,8 +383,9 @@ ns_job_signal_cb_test(void **state)
|
|
|
96373c |
{
|
|
|
96373c |
struct ns_thrpool_t *tp = *state;
|
|
|
96373c |
struct ns_job_t *job = NULL;
|
|
|
96373c |
+ struct timespec timeout = {1, 0};
|
|
|
96373c |
|
|
|
96373c |
- PR_Lock(cb_lock);
|
|
|
96373c |
+ pthread_mutex_lock(&cb_lock);
|
|
|
96373c |
assert_int_equal(
|
|
|
96373c |
ns_add_signal_job(tp, SIGUSR1, NS_JOB_SIGNAL, ns_init_test_job_cb, NULL, &job),
|
|
|
96373c |
NS_SUCCESS);
|
|
|
96373c |
@@ -376,8 +395,8 @@ ns_job_signal_cb_test(void **state)
|
|
|
96373c |
/* Send the signal ... */
|
|
|
96373c |
raise(SIGUSR1);
|
|
|
96373c |
|
|
|
96373c |
- PR_WaitCondVar(cb_cond, PR_SecondsToInterval(1));
|
|
|
96373c |
- PR_Unlock(cb_lock);
|
|
|
96373c |
+ assert(cond_wait_rel(&cb_cond, &cb_lock, &timeout) == 0);
|
|
|
96373c |
+ pthread_mutex_unlock(&cb_lock);
|
|
|
96373c |
|
|
|
96373c |
assert_int_equal(cb_check, 1);
|
|
|
96373c |
|
|
|
96373c |
@@ -408,12 +427,11 @@ ns_job_neg_timeout_test(void **state)
|
|
|
96373c |
static void
|
|
|
96373c |
ns_timer_job_cb(struct ns_job_t *job)
|
|
|
96373c |
{
|
|
|
96373c |
- cb_check += 1;
|
|
|
96373c |
ns_job_done(job);
|
|
|
96373c |
- PR_Lock(cb_lock);
|
|
|
96373c |
- PR_NotifyCondVar(cb_cond);
|
|
|
96373c |
- /* Disarm ourselves */
|
|
|
96373c |
- PR_Unlock(cb_lock);
|
|
|
96373c |
+ pthread_mutex_lock(&cb_lock);
|
|
|
96373c |
+ cb_check += 1;
|
|
|
96373c |
+ pthread_cond_signal(&cb_cond);
|
|
|
96373c |
+ pthread_mutex_unlock(&cb_lock);
|
|
|
96373c |
}
|
|
|
96373c |
|
|
|
96373c |
static void
|
|
|
96373c |
@@ -421,16 +439,19 @@ ns_job_timer_test(void **state)
|
|
|
96373c |
{
|
|
|
96373c |
struct ns_thrpool_t *tp = *state;
|
|
|
96373c |
struct ns_job_t *job = NULL;
|
|
|
96373c |
- struct timeval tv = {2, 0};
|
|
|
96373c |
+ struct timeval tv = {3, 0};
|
|
|
96373c |
+ struct timespec timeout = {2, 0};
|
|
|
96373c |
|
|
|
96373c |
- PR_Lock(cb_lock);
|
|
|
96373c |
+ pthread_mutex_lock(&cb_lock);
|
|
|
96373c |
assert_true(ns_add_timeout_job(tp, &tv, NS_JOB_THREAD, ns_timer_job_cb, NULL, &job) == NS_SUCCESS);
|
|
|
96373c |
|
|
|
96373c |
- PR_WaitCondVar(cb_cond, PR_SecondsToInterval(1));
|
|
|
96373c |
+ cond_wait_rel(&cb_cond, &cb_lock, &timeout);
|
|
|
96373c |
+ // pthread_mutex_unlock(&cb_lock);
|
|
|
96373c |
assert_int_equal(cb_check, 0);
|
|
|
96373c |
|
|
|
96373c |
- PR_WaitCondVar(cb_cond, PR_SecondsToInterval(2));
|
|
|
96373c |
- PR_Unlock(cb_lock);
|
|
|
96373c |
+ // pthread_mutex_lock(&cb_lock);
|
|
|
96373c |
+ cond_wait_rel(&cb_cond, &cb_lock, &timeout);
|
|
|
96373c |
+ pthread_mutex_unlock(&cb_lock);
|
|
|
96373c |
assert_int_equal(cb_check, 1);
|
|
|
96373c |
}
|
|
|
96373c |
|
|
|
96373c |
@@ -441,7 +462,9 @@ ns_job_timer_test(void **state)
|
|
|
96373c |
static void
|
|
|
96373c |
ns_timer_persist_job_cb(struct ns_job_t *job)
|
|
|
96373c |
{
|
|
|
96373c |
+ pthread_mutex_lock(&cb_lock);
|
|
|
96373c |
cb_check += 1;
|
|
|
96373c |
+ pthread_mutex_unlock(&cb_lock);
|
|
|
96373c |
if (cb_check < 10) {
|
|
|
96373c |
ns_job_rearm(job);
|
|
|
96373c |
} else {
|
|
|
96373c |
@@ -456,16 +479,19 @@ ns_job_timer_persist_test(void **state)
|
|
|
96373c |
struct ns_job_t *job = NULL;
|
|
|
96373c |
struct timeval tv = {1, 0};
|
|
|
96373c |
|
|
|
96373c |
- PR_Lock(cb_lock);
|
|
|
96373c |
assert_true(ns_add_timeout_job(tp, &tv, NS_JOB_THREAD, ns_timer_persist_job_cb, NULL, &job) == NS_SUCCESS);
|
|
|
96373c |
|
|
|
96373c |
PR_Sleep(PR_SecondsToInterval(5));
|
|
|
96373c |
|
|
|
96373c |
+ pthread_mutex_lock(&cb_lock);
|
|
|
96373c |
assert_true(cb_check <= 6);
|
|
|
96373c |
+ pthread_mutex_unlock(&cb_lock);
|
|
|
96373c |
|
|
|
96373c |
PR_Sleep(PR_SecondsToInterval(6));
|
|
|
96373c |
|
|
|
96373c |
+ pthread_mutex_lock(&cb_lock);
|
|
|
96373c |
assert_int_equal(cb_check, 10);
|
|
|
96373c |
+ pthread_mutex_unlock(&cb_lock);
|
|
|
96373c |
}
|
|
|
96373c |
|
|
|
96373c |
int
|
|
|
96373c |
--
|
|
|
96373c |
2.13.6
|
|
|
96373c |
|