Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

timer_create.c

Go to the documentation of this file.
00001 /*
00002 ** Copyright (C) 2005 by Kevin L. Mitchell <klmitch@mit.edu>
00003 **
00004 ** This program is free software; you can redistribute it and/or modify
00005 ** it under the terms of the GNU General Public License as published by
00006 ** the Free Software Foundation; either version 2 of the License, or
00007 ** (at your option) any later version.
00008 **
00009 ** This program is distributed in the hope that it will be useful,
00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 ** GNU General Public License for more details.
00013 **
00014 ** You should have received a copy of the GNU General Public License
00015 ** along with this program; if not, write to the Free Software
00016 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 **
00018 ** @(#)$Id: timer_create.c,v 1.3 2005/10/25 01:46:17 klmitch Exp $
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   /* Let's add the timer to the tree... */
00041   if (!ctx->ec_timtree.tt_root) { /* tree is empty... */
00042     ctx->ec_timtree.tt_root = tim; /* put timer at root... */
00043 
00044     tt_node_init(tim, 0, 0); /* initialize timer node */
00045   } else if (!ctx->ec_timtree.tt_insert) { /* no insertion cursor? */
00046     ev_assert(ctx->ec_timtree.tt_root);
00047 
00048     ctx->ec_timtree.tt_root->ti_node.tn_left = tim; /* put on the left */
00049     ctx->ec_timtree.tt_insert = ctx->ec_timtree.tt_root; /* insert at 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     /* insertion cursor points at half-full node, so insert there */
00056     ctx->ec_timtree.tt_insert->ti_node.tn_right = tim;
00057 
00058     tt_node_init(tim, ctx->ec_timtree.tt_insert, /* initialize timer node */
00059                  ctx->ec_timtree.tt_insert->ti_node.tn_left);
00060   } else { /* insertion cursor points at a full node... */
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     /* add timer to next timer after insertion cursor */
00065     ctx->ec_timtree.tt_insert->ti_node.tn_next->ti_node.tn_left = tim;
00066 
00067     /* initialize the timer node */
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     /* move the insertion cursor */
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))) /* heapify the thing */
00076     timer_destroy(ctx, tim); /* failed, destroy the timer... */
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(); /* make sure library is initialized... */
00090 
00091   /* sanity-check the arguments... */
00092   if (!ec_verify(ctx) || (type != TT_ABSOLUTE && type != TT_RELATIVE &&
00093                           type != TT_PERIODIC) || !value)
00094     ev_return(EINVAL);
00095 
00096   /* Let's allocate a generator... */
00097   if ((err = event_gen_alloc(ctx, EGT_TIMER, &tim)))
00098     ev_return(err);
00099 
00100   /* Set callback information */
00101   eg_callback_set(tim, call);
00102   eg_calldata_set(tim, data);
00103 
00104   /* Now initialize the timer fields... */
00105   tim->ti_type = type;
00106   tim->ti_value = *value;
00107   ti_expire_comp(tim); /* compute expiration time... */
00108 
00109   /* Walk through all the timer engines... */
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))) { /* add to engine... */
00113       /* oops!  Error occurred.  Walk engines backwards and remove timer */
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); /* release timer memory */
00118 
00119       ev_return(err); /* return the error */
00120     }
00121 
00122   if ((err = _timer_insert(ctx, tim))) /* insert into the tree */
00123     ev_return(err);
00124 
00125   eg_ref_inc(ctx, tim); /* increment the reference count */
00126 
00127   if (tim_p) /* did caller want the timer? */
00128     *tim_p = tim; /* then return it */
00129 
00130   ev_return(0);
00131 }

Generated on Wed Dec 28 23:36:56 2005 for event by  doxygen 1.4.4