Annotation of embedaddon/bird/lib/event.c, revision 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>