#include <isc/barrier.h>
#include <isc/condition.h>
#include <isc/job.h>
-#include <isc/list.h>
#include <isc/loop.h>
#include <isc/magic.h>
#include <isc/mem.h>
#include <isc/refcount.h>
#include <isc/result.h>
#include <isc/signal.h>
+#include <isc/stack.h>
#include <isc/strerr.h>
#include <isc/thread.h>
#include <isc/util.h>
/*
* Now send the half-initialized job to the loop queue.
+ *
+ * The ISC_ASTACK_PUSH is counterintuitive here, but uv_idle
+ * drains its queue backwards, so if there's more than one event
+ * to be processed then they need to be in reverse order.
*/
- LOCK(&loop->queue_lock);
- ISC_LIST_APPEND(loop->queue_jobs, job, link);
- UNLOCK(&loop->queue_lock);
+ ISC_ASTACK_PUSH(loop->queue_jobs, job, link);
r = uv_async_send(&loop->queue_trigger);
UV_RUNTIME_CHECK(uv_async_send, r);
static void
queue_cb(uv_async_t *handle) {
isc_loop_t *loop = uv_handle_get_data(handle);
- isc_job_t *job = NULL;
- ISC_LIST(isc_job_t) list;
REQUIRE(VALID_LOOP(loop));
- ISC_LIST_INIT(list);
-
- LOCK(&loop->queue_lock);
- ISC_LIST_MOVE(list, loop->queue_jobs);
- UNLOCK(&loop->queue_lock);
+ ISC_STACK(isc_job_t) drain = ISC_ASTACK_TO_STACK(loop->queue_jobs);
+ isc_job_t *job = ISC_STACK_POP(drain, link);
- /*
- * The ISC_LIST_TAIL is counterintuitive here, but uv_idle
- * drains its queue backwards, so if there's more than one event to
- * be processed then they need to be in reverse order.
- */
- job = ISC_LIST_TAIL(list);
while (job != NULL) {
- isc_job_t *next = ISC_LIST_PREV(job, link);
- ISC_LIST_UNLINK(list, job, link);
-
isc__job_init(loop, job);
isc__job_run(job);
- job = next;
+ job = ISC_STACK_POP(drain, link);
}
}
*loop = (isc_loop_t){
.tid = tid,
.loopmgr = loopmgr,
+ .queue_jobs = ISC_ASTACK_INITIALIZER,
+ .setup_jobs = ISC_LIST_INITIALIZER,
+ .teardown_jobs = ISC_LIST_INITIALIZER,
};
int r = uv_loop_init(&loop->loop);
isc_mem_create(&loop->mctx);
isc_mem_setname(loop->mctx, name);
- isc_mutex_init(&loop->queue_lock);
-
- ISC_LIST_INIT(loop->queue_jobs);
- ISC_LIST_INIT(loop->setup_jobs);
- ISC_LIST_INIT(loop->teardown_jobs);
-
isc_refcount_init(&loop->references, 1);
loop->magic = LOOP_MAGIC;
int r = uv_loop_close(&loop->loop);
UV_RUNTIME_CHECK(uv_loop_close, r);
- isc_mutex_destroy(&loop->queue_lock);
- INSIST(ISC_LIST_EMPTY(loop->queue_jobs));
+ INSIST(ISC_ASTACK_EMPTY(loop->queue_jobs));
loop->magic = 0;
#include <isc/refcount.h>
#include <isc/result.h>
#include <isc/signal.h>
+#include <isc/stack.h>
#include <isc/thread.h>
#include <isc/types.h>
#include <isc/uv.h>
#define VALID_LOOP(t) ISC_MAGIC_VALID(t, LOOP_MAGIC)
typedef ISC_LIST(isc_job_t) isc_joblist_t;
+typedef ISC_ASTACK(isc_job_t) isc_jobstack_t;
struct isc_loop {
int magic;
/* Async queue */
uv_async_t queue_trigger;
- isc_mutex_t queue_lock;
- isc_joblist_t queue_jobs;
+ isc_jobstack_t queue_jobs;
/* Pause */
uv_async_t pause_trigger;
isc_loop_t *loop;
isc_job_cb cb;
void *cbarg;
- LINK(isc_job_t) link;
+ ISC_LINK(isc_job_t) link;
};
/*