00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00027 #include "engines_int.h"
00028
00029 RCSTAG("@(#)$Id: timer_destroy.c,v 1.2 2005/09/15 18:14:11 klmitch Exp $");
00030
00031 ev_err_t
00032 _timer_untree(ev_ctx_t *ctx, ev_tim_t *tim)
00033 {
00034 ev_tim_t *end;
00035 ev_err_t err = 0;
00036
00037 ev_trace();
00038
00039 ev_assert(ctx->ec_timtree.tt_root);
00040
00041
00042 if (!ctx->ec_timtree.tt_root->ti_node.tn_left) {
00043 ev_assert(ctx->ec_timtree.tt_root == tim);
00044
00045
00046 ctx->ec_timtree.tt_root = 0;
00047 ctx->ec_timtree.tt_insert = 0;
00048
00049
00050 tt_node_init(tim, 0, 0);
00051
00052 ev_return(0);
00053 }
00054
00055 ev_assert(ctx->ec_timtree.tt_insert);
00056
00057
00058 if (ctx->ec_timtree.tt_insert->ti_node.tn_right) {
00059
00060 end = ctx->ec_timtree.tt_insert->ti_node.tn_right;
00061 ctx->ec_timtree.tt_insert->ti_node.tn_right = 0;
00062 } else {
00063 end = ctx->ec_timtree.tt_insert->ti_node.tn_left;
00064 ctx->ec_timtree.tt_insert->ti_node.tn_left = 0;
00065
00066
00067 ctx->ec_timtree.tt_insert =
00068 (ctx->ec_timtree.tt_insert->ti_node.tn_prev == ctx->ec_timtree.tt_root &&
00069 !ctx->ec_timtree.tt_root->ti_node.tn_left) ?
00070 0 : ctx->ec_timtree.tt_insert->ti_node.tn_prev;
00071 }
00072
00073 ev_assert(end->ti_node.tn_prev);
00074 ev_assert(!end->ti_node.tn_next);
00075
00076
00077 end->ti_node.tn_prev->ti_node.tn_next = 0;
00078
00079 if (end != tim) {
00080 int tmp;
00081
00082 end->ti_node = tim->ti_node;
00083 tt_node_fix(end);
00084
00085 if (!end->ti_node.tn_parent)
00086 ctx->ec_timtree.tt_root = end;
00087 else if (end->ti_node.tn_parent->ti_node.tn_left == tim)
00088
00089 end->ti_node.tn_parent->ti_node.tn_left = end;
00090 else
00091 end->ti_node.tn_parent->ti_node.tn_right = end;
00092
00093 if (ctx->ec_timtree.tt_insert == tim)
00094 ctx->ec_timtree.tt_insert = end;
00095
00096 if ((tmp = tv_comp(&end->ti_expire, &tim->ti_expire)) < 0)
00097
00098 err = _timer_heapify_down(ctx, end);
00099 else if (tmp > 0)
00100 err = _timer_heapify_up(ctx, end);
00101 }
00102
00103 tt_node_init(tim, 0, 0);
00104
00105 ev_return(err);
00106 }
00107
00108 ev_err_t
00109 timer_destroy(ev_ctx_t *ctx, ev_tim_t *tim)
00110 {
00111 ev_engine_t *eng;
00112 ev_err_t err, err2;
00113
00114 ev_init();
00115
00116
00117 if (!ec_verify(ctx) || !ti_verify(tim) || eg_context(tim) != ctx)
00118 ev_return(EINVAL);
00119
00120 if (eg_flags(tim) & EV_GEN_DELETED)
00121 ev_return(0);
00122
00123 err = _timer_untree(ctx, tim);
00124
00125
00126 for (eng = ctx->ec_timer.el_last; eng;
00127 eng = eng->eng_timer.eti_active.el_prev)
00128 if ((err2 = eng_tim_rem(ctx, eng, tim)) && !err)
00129 err = err2;
00130
00131 eg_flags_set(tim, EV_GEN_DELETED);
00132
00133
00134 eg_ref_dec(ctx, tim);
00135
00136 ev_return(err);
00137 }