File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / bird2 / lib / event.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Oct 21 16:03:56 2019 UTC (4 years, 8 months ago) by misho
Branches: bird2, MAIN
CVS tags: v2_0_7p0, HEAD
bird2 ver 2.0.7

    1: /*
    2:  *	BIRD Library -- Event Processing
    3:  *
    4:  *	(c) 1999 Martin Mares <mj@ucw.cz>
    5:  *
    6:  *	Can be freely distributed and used under the terms of the GNU GPL.
    7:  */
    8: 
    9: /**
   10:  * DOC: Events
   11:  *
   12:  * Events are there to keep track of deferred execution.
   13:  * Since BIRD is single-threaded, it requires long lasting tasks to be split to smaller
   14:  * parts, so that no module can monopolize the CPU. To split such a task, just create
   15:  * an &event resource, point it to the function you want to have called and call ev_schedule()
   16:  * to ask the core to run the event when nothing more important requires attention.
   17:  *
   18:  * You can also define your own event lists (the &event_list structure), enqueue your
   19:  * events in them and explicitly ask to run them.
   20:  */
   21: 
   22: #include "nest/bird.h"
   23: #include "lib/event.h"
   24: 
   25: event_list global_event_list;
   26: 
   27: inline void
   28: ev_postpone(event *e)
   29: {
   30:   if (ev_active(e))
   31:     {
   32:       rem_node(&e->n);
   33:       e->n.next = NULL;
   34:     }
   35: }
   36: 
   37: static void
   38: ev_dump(resource *r)
   39: {
   40:   event *e = (event *) r;
   41: 
   42:   debug("(code %p, data %p, %s)\n",
   43: 	e->hook,
   44: 	e->data,
   45: 	e->n.next ? "scheduled" : "inactive");
   46: }
   47: 
   48: static struct resclass ev_class = {
   49:   "Event",
   50:   sizeof(event),
   51:   (void (*)(resource *)) ev_postpone,
   52:   ev_dump,
   53:   NULL,
   54:   NULL
   55: };
   56: 
   57: /**
   58:  * ev_new - create a new event
   59:  * @p: resource pool
   60:  *
   61:  * This function creates a new event resource. To use it,
   62:  * you need to fill the structure fields and call ev_schedule().
   63:  */
   64: event *
   65: ev_new(pool *p)
   66: {
   67:   event *e = ralloc(p, &ev_class);
   68:   return e;
   69: }
   70: 
   71: /**
   72:  * ev_run - run an event
   73:  * @e: an event
   74:  *
   75:  * This function explicitly runs the event @e (calls its hook
   76:  * function) and removes it from an event list if it's linked to any.
   77:  *
   78:  * From the hook function, you can call ev_enqueue() or ev_schedule()
   79:  * to re-add the event.
   80:  */
   81: inline void
   82: ev_run(event *e)
   83: {
   84:   ev_postpone(e);
   85:   e->hook(e->data);
   86: }
   87: 
   88: /**
   89:  * ev_enqueue - enqueue an event
   90:  * @l: an event list
   91:  * @e: an event
   92:  *
   93:  * ev_enqueue() stores the event @e to the specified event
   94:  * list @l which can be run by calling ev_run_list().
   95:  */
   96: inline void
   97: ev_enqueue(event_list *l, event *e)
   98: {
   99:   ev_postpone(e);
  100:   add_tail(l, &e->n);
  101: }
  102: 
  103: /**
  104:  * ev_schedule - schedule an event
  105:  * @e: an event
  106:  *
  107:  * This function schedules an event by enqueueing it to a system-wide
  108:  * event list which is run by the platform dependent code whenever
  109:  * appropriate.
  110:  */
  111: void
  112: ev_schedule(event *e)
  113: {
  114:   ev_enqueue(&global_event_list, e);
  115: }
  116: 
  117: void io_log_event(void *hook, void *data);
  118: 
  119: /**
  120:  * ev_run_list - run an event list
  121:  * @l: an event list
  122:  *
  123:  * This function calls ev_run() for all events enqueued in the list @l.
  124:  */
  125: int
  126: ev_run_list(event_list *l)
  127: {
  128:   node *n;
  129:   list tmp_list;
  130: 
  131:   init_list(&tmp_list);
  132:   add_tail_list(&tmp_list, l);
  133:   init_list(l);
  134:   WALK_LIST_FIRST(n, tmp_list)
  135:     {
  136:       event *e = SKIP_BACK(event, n, n);
  137: 
  138:       /* This is ugly hack, we want to log just events executed from the main I/O loop */
  139:       if (l == &global_event_list)
  140: 	io_log_event(e->hook, e->data);
  141: 
  142:       ev_run(e);
  143:     }
  144:   return !EMPTY_LIST(*l);
  145: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>