diff options
Diffstat (limited to 'ctdb/lib/tevent/tevent_queue.c')
-rw-r--r-- | ctdb/lib/tevent/tevent_queue.c | 99 |
1 files changed, 91 insertions, 8 deletions
diff --git a/ctdb/lib/tevent/tevent_queue.c b/ctdb/lib/tevent/tevent_queue.c index 3715c35e4f..4750675802 100644 --- a/ctdb/lib/tevent/tevent_queue.c +++ b/ctdb/lib/tevent/tevent_queue.c @@ -144,17 +144,19 @@ static void tevent_queue_immediate_trigger(struct tevent_context *ev, q->list->trigger(q->list->req, q->list->private_data); } -bool tevent_queue_add(struct tevent_queue *queue, - struct tevent_context *ev, - struct tevent_req *req, - tevent_queue_trigger_fn_t trigger, - void *private_data) +static struct tevent_queue_entry *tevent_queue_add_internal( + struct tevent_queue *queue, + struct tevent_context *ev, + struct tevent_req *req, + tevent_queue_trigger_fn_t trigger, + void *private_data, + bool allow_direct) { struct tevent_queue_entry *e; e = talloc_zero(req, struct tevent_queue_entry); if (e == NULL) { - return false; + return NULL; } e->queue = queue; @@ -163,16 +165,53 @@ bool tevent_queue_add(struct tevent_queue *queue, e->trigger = trigger; e->private_data = private_data; + /* + * if there is no trigger, it is just a blocker + */ + if (trigger == NULL) { + e->triggered = true; + } + + if (queue->length > 0) { + /* + * if there are already entries in the + * queue do not optimize. + */ + allow_direct = false; + } + + if (req->async.fn != NULL) { + /* + * If the callers wants to optimize for the + * empty queue case, call the trigger only + * if there is no callback defined for the + * request yet. + */ + allow_direct = false; + } + DLIST_ADD_END(queue->list, e, struct tevent_queue_entry *); queue->length++; talloc_set_destructor(e, tevent_queue_entry_destructor); if (!queue->running) { - return true; + return e; } if (queue->list->triggered) { - return true; + return e; + } + + /* + * If allowed we directly call the trigger + * avoiding possible delays caused by + * an immediate event. + */ + if (allow_direct) { + queue->list->triggered = true; + queue->list->trigger(queue->list->req, + queue->list->private_data); + return e; } tevent_schedule_immediate(queue->immediate, @@ -180,9 +219,48 @@ bool tevent_queue_add(struct tevent_queue *queue, tevent_queue_immediate_trigger, queue); + return e; +} + +bool tevent_queue_add(struct tevent_queue *queue, + struct tevent_context *ev, + struct tevent_req *req, + tevent_queue_trigger_fn_t trigger, + void *private_data) +{ + struct tevent_queue_entry *e; + + e = tevent_queue_add_internal(queue, ev, req, + trigger, private_data, false); + if (e == NULL) { + return false; + } + return true; } +struct tevent_queue_entry *tevent_queue_add_entry( + struct tevent_queue *queue, + struct tevent_context *ev, + struct tevent_req *req, + tevent_queue_trigger_fn_t trigger, + void *private_data) +{ + return tevent_queue_add_internal(queue, ev, req, + trigger, private_data, false); +} + +struct tevent_queue_entry *tevent_queue_add_optimize_empty( + struct tevent_queue *queue, + struct tevent_context *ev, + struct tevent_req *req, + tevent_queue_trigger_fn_t trigger, + void *private_data) +{ + return tevent_queue_add_internal(queue, ev, req, + trigger, private_data, true); +} + void tevent_queue_start(struct tevent_queue *queue) { if (queue->running) { @@ -215,3 +293,8 @@ size_t tevent_queue_length(struct tevent_queue *queue) { return queue->length; } + +bool tevent_queue_running(struct tevent_queue *queue) +{ + return queue->running; +} |