summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nxt_conn_read.c4
-rw-r--r--src/nxt_timer.c135
-rw-r--r--src/nxt_timer.h36
3 files changed, 78 insertions, 97 deletions
diff --git a/src/nxt_conn_read.c b/src/nxt_conn_read.c
index 21086233..e458bf81 100644
--- a/src/nxt_conn_read.c
+++ b/src/nxt_conn_read.c
@@ -105,7 +105,7 @@ nxt_conn_io_read(nxt_task_t *task, void *obj, void *data)
* occured during read operation, it toggled write event
* internally so only read timer should be set.
*/
- if (c->read_timer.state == NXT_TIMER_DISABLED) {
+ if (!c->read_timer.enabled) {
nxt_conn_timer(engine, c, state, &c->read_timer);
}
@@ -117,7 +117,7 @@ nxt_conn_io_read(nxt_task_t *task, void *obj, void *data)
nxt_fd_event_enable_read(engine, &c->socket);
}
- if (state->timer_autoreset || c->read_timer.state == NXT_TIMER_DISABLED) {
+ if (state->timer_autoreset || !c->read_timer.enabled) {
nxt_conn_timer(engine, c, state, &c->read_timer);
}
}
diff --git a/src/nxt_timer.c b/src/nxt_timer.c
index f56ddeb6..97807d75 100644
--- a/src/nxt_timer.c
+++ b/src/nxt_timer.c
@@ -32,6 +32,10 @@ nxt_timers_init(nxt_timers_t *timers, nxt_uint_t mchanges)
{
nxt_rbtree_init(&timers->tree, nxt_timer_rbtree_compare);
+ if (mchanges > NXT_TIMER_MAX_CHANGES) {
+ mchanges = NXT_TIMER_MAX_CHANGES;
+ }
+
timers->mchanges = mchanges;
timers->changes = nxt_malloc(sizeof(nxt_timer_change_t) * mchanges);
@@ -71,66 +75,47 @@ nxt_timer_add(nxt_event_engine_t *engine, nxt_timer_t *timer,
time = engine->timers.now + timeout;
- if (timer->state != NXT_TIMER_CHANGING) {
+ nxt_debug(timer->task, "timer add: %M %M:%M", timer->time, timeout, time);
- if (nxt_timer_is_in_tree(timer)) {
+ timer->enabled = 1;
- diff = nxt_msec_diff(time, timer->time);
- /*
- * Use the previous timer if difference between it and the
- * new timer is less than required precision milliseconds: this
- * decreases number of rbtree operations for fast connections.
- */
- if (nxt_abs(diff) < timer->precision) {
- nxt_debug(timer->task, "timer previous: %M:%d",
- time, timer->state);
+ if (nxt_timer_is_in_tree(timer)) {
- timer->state = NXT_TIMER_WAITING;
- return;
- }
+ diff = nxt_msec_diff(time, timer->time);
+ /*
+ * Use the previous timer if difference between it and the
+ * new timer is less than required precision milliseconds: this
+ * decreases number of rbtree operations for fast connections.
+ */
+ if (nxt_abs(diff) < timer->precision) {
+ nxt_debug(timer->task, "timer previous: %M", time);
+
+ nxt_timer_change(engine, timer, NXT_TIMER_NOPE, 0);
+ return;
}
}
- nxt_debug(timer->task, "timer add: %M:%d %M:%M",
- timer->time, timer->state, timeout, time);
-
nxt_timer_change(engine, timer, NXT_TIMER_ADD, time);
}
-void
-nxt_timer_disable(nxt_event_engine_t *engine, nxt_timer_t *timer)
-{
- nxt_debug(timer->task, "timer disable: %M:%d", timer->time, timer->state);
-
- if (timer->state != NXT_TIMER_CHANGING) {
- timer->state = NXT_TIMER_DISABLED;
-
- } else {
- nxt_timer_change(engine, timer, NXT_TIMER_DISABLE, 0);
- }
-}
-
-
nxt_bool_t
nxt_timer_delete(nxt_event_engine_t *engine, nxt_timer_t *timer)
{
- nxt_bool_t pending;
+ nxt_debug(timer->task, "timer delete: %M", timer->time);
+
+ timer->enabled = 0;
- if (nxt_timer_is_in_tree(timer) || timer->state == NXT_TIMER_CHANGING) {
- nxt_debug(timer->task, "timer delete: %M:%d",
- timer->time, timer->state);
+ if (nxt_timer_is_in_tree(timer)) {
nxt_timer_change(engine, timer, NXT_TIMER_DELETE, 0);
return 1;
}
- pending = (timer->state == NXT_TIMER_ENQUEUED);
-
- timer->state = NXT_TIMER_DISABLED;
+ nxt_timer_change(engine, timer, NXT_TIMER_NOPE, 0);
- return pending;
+ return (timer->queued || timer->change != NXT_TIMER_NO_CHANGE);
}
@@ -143,31 +128,35 @@ nxt_timer_change(nxt_event_engine_t *engine, nxt_timer_t *timer,
timers = &engine->timers;
- if (timers->nchanges >= timers->mchanges) {
- nxt_timer_changes_commit(engine);
+ if (timer->change == NXT_TIMER_NO_CHANGE) {
+
+ if (change == NXT_TIMER_NOPE) {
+ return;
+ }
+
+ if (timers->nchanges >= timers->mchanges) {
+ nxt_timer_changes_commit(engine);
+ }
+
+ timers->nchanges++;
+ timer->change = timers->nchanges;
}
nxt_debug(timer->task, "timer change: %M:%d", time, change);
- timer->state = NXT_TIMER_CHANGING;
-
- ch = &timers->changes[timers->nchanges];
+ ch = &timers->changes[timer->change - 1];
ch->change = change;
ch->time = time;
ch->timer = timer;
-
- timers->nchanges++;
}
static void
nxt_timer_changes_commit(nxt_event_engine_t *engine)
{
- int32_t diff;
nxt_timer_t *timer;
nxt_timers_t *timers;
- nxt_timer_state_t state;
nxt_timer_change_t *ch, *end;
timers = &engine->timers;
@@ -178,28 +167,16 @@ nxt_timer_changes_commit(nxt_event_engine_t *engine)
end = ch + timers->nchanges;
while (ch < end) {
- state = NXT_TIMER_DISABLED;
-
timer = ch->timer;
switch (ch->change) {
+ case NXT_TIMER_NOPE:
+ break;
+
case NXT_TIMER_ADD:
if (nxt_timer_is_in_tree(timer)) {
-
- diff = nxt_msec_diff(ch->time, timer->time);
- /* See the comment in nxt_timer_add(). */
-
- if (nxt_abs(diff) < timer->precision) {
- nxt_debug(timer->task, "timer rbtree previous: %M:%d",
- ch->time, timer->state);
-
- state = NXT_TIMER_WAITING;
- break;
- }
-
- nxt_debug(timer->task, "timer rbtree delete: %M:%d",
- timer->time, timer->state);
+ nxt_debug(timer->task, "timer rbtree delete: %M", timer->time);
nxt_rbtree_delete(&timers->tree, &timer->node);
}
@@ -210,26 +187,19 @@ nxt_timer_changes_commit(nxt_event_engine_t *engine)
nxt_rbtree_insert(&timers->tree, &timer->node);
nxt_timer_in_tree_set(timer);
- state = NXT_TIMER_WAITING;
break;
case NXT_TIMER_DELETE:
- if (nxt_timer_is_in_tree(timer)) {
- nxt_debug(timer->task, "timer rbtree delete: %M:%d",
- timer->time, timer->state);
+ nxt_debug(timer->task, "timer rbtree delete: %M", timer->time);
- nxt_rbtree_delete(&timers->tree, &timer->node);
- nxt_timer_in_tree_clear(timer);
- }
+ nxt_rbtree_delete(&timers->tree, &timer->node);
+ nxt_timer_in_tree_clear(timer);
break;
-
- case NXT_TIMER_DISABLE:
- break;
}
- timer->state = state;
+ timer->change = NXT_TIMER_NO_CHANGE;
ch++;
}
@@ -270,7 +240,7 @@ nxt_timer_find(nxt_event_engine_t *engine)
* return much earlier and the disabled timer can be reactivated.
*/
- if (timer->state != NXT_TIMER_DISABLED) {
+ if (timer->enabled) {
time = timer->time;
timers->minimum = time;
@@ -324,14 +294,13 @@ nxt_timer_expire(nxt_event_engine_t *engine, nxt_msec_t now)
next = nxt_rbtree_node_successor(tree, node);
- nxt_debug(timer->task, "timer expire delete: %M:%d",
- timer->time, timer->state);
+ nxt_debug(timer->task, "timer expire delete: %M", timer->time);
nxt_rbtree_delete(tree, &timer->node);
nxt_timer_in_tree_clear(timer);
- if (timer->state != NXT_TIMER_DISABLED) {
- timer->state = NXT_TIMER_ENQUEUED;
+ if (timer->enabled) {
+ timer->queued = 1;
nxt_work_queue_add(timer->work_queue, nxt_timer_handler,
timer->task, timer, NULL);
@@ -347,8 +316,10 @@ nxt_timer_handler(nxt_task_t *task, void *obj, void *data)
timer = obj;
- if (timer->state == NXT_TIMER_ENQUEUED) {
- timer->state = NXT_TIMER_DISABLED;
+ timer->queued = 0;
+
+ if (timer->enabled && timer->change == NXT_TIMER_NO_CHANGE) {
+ timer->enabled = 0;
timer->handler(task, timer, NULL);
}
diff --git a/src/nxt_timer.h b/src/nxt_timer.h
index 6531657d..211564d6 100644
--- a/src/nxt_timer.h
+++ b/src/nxt_timer.h
@@ -13,20 +13,24 @@
//#define NXT_TIMER_DEFAULT_PRECISION 1
-typedef enum {
- NXT_TIMER_DISABLED = 0,
- NXT_TIMER_CHANGING,
- NXT_TIMER_WAITING,
- NXT_TIMER_ENQUEUED,
-} nxt_timer_state_t;
+/*
+ * The nxt_timer_t structure can hold up to 14 bits of change index,
+ * but 0 reserved for NXT_TIMER_NO_CHANGE.
+ */
+#define NXT_TIMER_MAX_CHANGES 16383
+#define NXT_TIMER_NO_CHANGE 0
typedef struct {
/* The rbtree node must be the first field. */
NXT_RBTREE_NODE (node);
- nxt_timer_state_t state:8;
uint8_t precision;
+
+ uint16_t change:14;
+ uint16_t enabled:1;
+ uint16_t queued:1;
+
nxt_msec_t time;
nxt_work_queue_t *work_queue;
@@ -37,13 +41,13 @@ typedef struct {
} nxt_timer_t;
-#define NXT_TIMER { NXT_RBTREE_NODE_INIT, NXT_TIMER_DISABLED, \
- 0, 0, NULL, NULL, NULL, NULL }
+#define NXT_TIMER { NXT_RBTREE_NODE_INIT, 0, NXT_TIMER_NO_CHANGE, \
+ 0, 0, 0, NULL, NULL, NULL, NULL }
typedef enum {
- NXT_TIMER_ADD = 0,
- NXT_TIMER_DISABLE,
+ NXT_TIMER_NOPE = 0,
+ NXT_TIMER_ADD,
NXT_TIMER_DELETE,
} nxt_timer_operation_t;
@@ -94,10 +98,16 @@ void nxt_timer_expire(nxt_event_engine_t *engine, nxt_msec_t now);
NXT_EXPORT void nxt_timer_add(nxt_event_engine_t *engine, nxt_timer_t *timer,
nxt_msec_t timeout);
-NXT_EXPORT void nxt_timer_disable(nxt_event_engine_t *engine,
- nxt_timer_t *timer);
NXT_EXPORT nxt_bool_t nxt_timer_delete(nxt_event_engine_t *engine,
nxt_timer_t *timer);
+nxt_inline void
+nxt_timer_disable(nxt_event_engine_t *engine, nxt_timer_t *timer)
+{
+ nxt_debug(timer->task, "timer disable: %M", timer->time);
+
+ timer->enabled = 0;
+}
+
#endif /* _NXT_TIMER_H_INCLUDED_ */