Annotation of embedaddon/bird/lib/event.c, revision 1.1.1.1

1.1       misho       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>