00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00029 #include "engines_int.h"
00030
00031 RCSTAG("@(#)$Id: timer_create.c,v 1.3 2005/10/25 01:46:17 klmitch Exp $");
00032
00033 ev_err_t
00034 _timer_insert(ev_ctx_t *ctx, ev_tim_t *tim)
00035 {
00036 ev_err_t err = 0;
00037
00038 ev_trace();
00039
00040
00041 if (!ctx->ec_timtree.tt_root) {
00042 ctx->ec_timtree.tt_root = tim;
00043
00044 tt_node_init(tim, 0, 0);
00045 } else if (!ctx->ec_timtree.tt_insert) {
00046 ev_assert(ctx->ec_timtree.tt_root);
00047
00048 ctx->ec_timtree.tt_root->ti_node.tn_left = tim;
00049 ctx->ec_timtree.tt_insert = ctx->ec_timtree.tt_root;
00050
00051 tt_node_init(tim, ctx->ec_timtree.tt_root, ctx->ec_timtree.tt_root);
00052 } else if (!ctx->ec_timtree.tt_insert->ti_node.tn_right) {
00053 ev_assert(ctx->ec_timtree.tt_insert->ti_node.tn_left);
00054
00055
00056 ctx->ec_timtree.tt_insert->ti_node.tn_right = tim;
00057
00058 tt_node_init(tim, ctx->ec_timtree.tt_insert,
00059 ctx->ec_timtree.tt_insert->ti_node.tn_left);
00060 } else {
00061 ev_assert(ctx->ec_timtree.tt_insert->ti_node.tn_left);
00062 ev_assert(ctx->ec_timtree.tt_insert->ti_node.tn_next);
00063
00064
00065 ctx->ec_timtree.tt_insert->ti_node.tn_next->ti_node.tn_left = tim;
00066
00067
00068 tt_node_init(tim, ctx->ec_timtree.tt_insert->ti_node.tn_next,
00069 ctx->ec_timtree.tt_insert->ti_node.tn_right);
00070
00071
00072 ctx->ec_timtree.tt_insert = ctx->ec_timtree.tt_insert->ti_node.tn_next;
00073 }
00074
00075 if ((err = _timer_heapify_up(ctx, tim)))
00076 timer_destroy(ctx, tim);
00077
00078 ev_return(err);
00079 }
00080
00081 ev_err_t
00082 timer_create(ev_ctx_t *ctx, ev_timtype_t type, struct timeval *value,
00083 ev_call_t call, void *data, ev_tim_t **tim_p)
00084 {
00085 ev_engine_t *eng;
00086 ev_err_t err = 0;
00087 ev_tim_t *tim;
00088
00089 ev_init();
00090
00091
00092 if (!ec_verify(ctx) || (type != TT_ABSOLUTE && type != TT_RELATIVE &&
00093 type != TT_PERIODIC) || !value)
00094 ev_return(EINVAL);
00095
00096
00097 if ((err = event_gen_alloc(ctx, EGT_TIMER, &tim)))
00098 ev_return(err);
00099
00100
00101 eg_callback_set(tim, call);
00102 eg_calldata_set(tim, data);
00103
00104
00105 tim->ti_type = type;
00106 tim->ti_value = *value;
00107 ti_expire_comp(tim);
00108
00109
00110 for (eng = ctx->ec_timer.el_first; eng;
00111 eng = eng->eng_timer.eti_active.el_next)
00112 if ((err = eng_tim_add(ctx, eng, tim))) {
00113
00114 for (; eng; eng = eng->eng_timer.eti_active.el_prev)
00115 eng_tim_rem(ctx, eng, tim);
00116
00117 event_gen_release(ctx, (ev_genhdr_t *)tim);
00118
00119 ev_return(err);
00120 }
00121
00122 if ((err = _timer_insert(ctx, tim)))
00123 ev_return(err);
00124
00125 eg_ref_inc(ctx, tim);
00126
00127 if (tim_p)
00128 *tim_p = tim;
00129
00130 ev_return(0);
00131 }