- 论坛徽章:
- 0
|
The Atheme projects
http://www.atheme.org/project/mowgli
libmowgli
A useful collection of routines for programming. Performance and usability-oriented extensions to C.
libmowgli Contains:
mowgli_alloc: A safe wrapper around malloc/free.
mowgli_argstack: Safe serialization of valists.
mowgli_assert: Various assertion routines that can be used.
mowgli_bitvector: Bitmasks with an unlimited level of precision.
mowgli_dictionary: A keyword-backed definition hashtable class.
mowgli_error_backtrace: Provide feedback to users on what caused the error they are recieving.
mowgli_exception: Assertions with user feedback.
mowgli_formatter: A simple token formatter which is sometimes useful.
mowgli_global_storage: A simple global storage library.
mowgli_hash: A portable implementation of the FNV-1 hash.
mowgli_heap: An optimistic heap-based memory allocator.
mowgli_hook: A simple hooks API you can use for your application, which allows for hooks to provide both application data and user data.
mowgli_ioevent: Portable I/O completion ports for many OSes.
mowgli_list: A high performance linked lists implementation with O(1) scalability for most common operations.
mowgli_logger: An internal class for handling logging of exceptions.
mowgli_memorypool: A class which allows for memory pooling.
mowgli_module: A wrapper around dlopen(3) and dlsym(3).
mowgli_object: A simple class which provides reference counted pointers and polymorphism of structs.
mowgli_object_class: Classing and subclassing for objects.
mowgli_object_metadata: Metadata for objects.
mowgli_object_messaging: Messaging and signalling for objects.
mowgli_queue: A simple class which implements double-ended queues.
mowgli_random: A high performance psuedo-random number generator.
mowgli_signal: A wrapper for sigaction(2).
mowgli_spinlock: Portable spinlocks.
小库,就20几个文件
你可以参考它的事件循环处理代码,看下它的封装。
libmowgli-2.0.0/src/libmowgli/eventloop# cat timer.c
/*
* Copyright (c) 2011 William Pitcock <nenolod@dereferenced.org>
* Copyright (c) 2005-2007 Atheme Project (http://www.atheme.org)
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "mowgli.h"
static mowgli_heap_t *timer_heap = NULL;
static mowgli_eventloop_timer_t *mowgli_timer_add_real(mowgli_eventloop_t *eventloop,
const char *name, mowgli_event_dispatch_func_t *func, void *arg, time_t when, time_t frequency)
{
mowgli_eventloop_timer_t *timer;
return_val_if_fail(eventloop != NULL, NULL);
return_val_if_fail(func != NULL, NULL);
if (timer_heap == NULL)
timer_heap = mowgli_heap_create(sizeof(mowgli_eventloop_timer_t), 16, BH_NOW);
timer = mowgli_heap_alloc(timer_heap);
timer->func = func;
timer->name = name;
timer->arg = arg;
timer->when = mowgli_eventloop_get_time(eventloop) + when;
timer->frequency = frequency;
timer->active = true;
if (eventloop->deadline <= mowgli_eventloop_get_time(eventloop) || timer->when <= eventloop->deadline)
eventloop->deadline = timer->when;
mowgli_node_add(timer, &timer->node, &eventloop->timer_list);
#ifdef DEBUG
mowgli_log("[timer(%p) add when:%d active:%d] [eventloop deadline:%d]", timer, timer->when, timer->active, eventloop->deadline);
#endif
return timer;
}
/* add an event to the table to be continually ran */
mowgli_eventloop_timer_t *mowgli_timer_add(mowgli_eventloop_t *eventloop, const char *name, mowgli_event_dispatch_func_t *func, void *arg, time_t when)
{
return mowgli_timer_add_real(eventloop, name, func, arg, when, when);
}
/* adds an event to the table to be ran only once */
mowgli_eventloop_timer_t *mowgli_timer_add_once(mowgli_eventloop_t *eventloop, const char *name, mowgli_event_dispatch_func_t *func, void *arg, time_t when)
{
return mowgli_timer_add_real(eventloop, name, func, arg, when, 0);
}
/* delete an event from the table */
void mowgli_timer_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_timer_t *timer)
{
return_if_fail(eventloop != NULL);
return_if_fail(timer != NULL);
if (eventloop->last_ran == timer->name)
eventloop->last_ran = "<removed>";
mowgli_node_delete(&timer->node, &eventloop->timer_list);
mowgli_heap_free(timer_heap, timer);
}
/* checks all pending events */
void mowgli_eventloop_run_timers(mowgli_eventloop_t *eventloop)
{
mowgli_node_t *n, *tn;
time_t currtime;
return_if_fail(eventloop != NULL);
currtime = mowgli_eventloop_get_time(eventloop);
MOWGLI_ITER_FOREACH_SAFE(n, tn, eventloop->timer_list.head)
{
mowgli_eventloop_timer_t *timer = n->data;
if (timer->active && timer->when <= currtime)
{
/* now we call it */
eventloop->last_ran = timer->name;
timer->func(timer->arg);
/* invalidate eventloop sleep-until time */
eventloop->deadline = -1;
/* event is scheduled more than once */
if (timer->frequency)
timer->when = currtime + timer->frequency;
else
{
/* XXX: yuck. find a better way to handle this. */
eventloop->last_ran = "<onceonly>";
mowgli_timer_destroy(eventloop, timer);
}
}
}
}
/* returns the time the next mowgli_timer_run() should happen */
time_t mowgli_eventloop_next_timer(mowgli_eventloop_t *eventloop)
{
mowgli_node_t *n;
return_val_if_fail(eventloop != NULL, 0);
if (eventloop->deadline == -1)
{
MOWGLI_ITER_FOREACH(n, eventloop->timer_list.head)
{
mowgli_eventloop_timer_t *timer = n->data;
if (timer->active && (timer->when < eventloop->deadline || eventloop->deadline == -1))
eventloop->deadline = timer->when;
#ifdef DEBUG
mowgli_log("timer %p active:%d when:%ld deadline:%ld", timer, timer->active, timer->when, eventloop->deadline);
#endif
}
}
#ifdef DEBUG
mowgli_log("eventloop deadline:%ld", eventloop->deadline);
#endif
return eventloop->deadline;
}
/* finds an event in the table */
mowgli_eventloop_timer_t *mowgli_timer_find(mowgli_eventloop_t *eventloop, mowgli_event_dispatch_func_t *func, void *arg)
{
mowgli_node_t *n;
return_val_if_fail(eventloop != NULL, NULL);
return_val_if_fail(func != NULL, NULL);
MOWGLI_ITER_FOREACH(n, eventloop->timer_list.head)
{
mowgli_eventloop_timer_t *timer = n->data;
if (timer->func == func && timer->arg == arg)
return timer;
}
return NULL;
}
/* vim:cinoptions=>s,e0,n0,f0,{0,}0,^0,=s,ps,t0,c3,+s,(2s,us,)20,*30,gs,hs
* vim:ts=8
* vim:sw=8
* vim:noexpandtab
*/
|
|