*** empty log message ***

This commit is contained in:
Marc Alexander Lehmann 2011-12-20 04:08:35 +00:00
parent 8e8d1095b8
commit eeab0b6f08
4 changed files with 99 additions and 79 deletions

View File

@ -3,7 +3,6 @@ Revision history for libev, a high-performance and full-featured event loop.
TODO: ev_loop_wakeup
TODO: EV_NO_THREADS/NO_SMP and/or EV_USE_PTHREADS or so. also document.
TODO: #define EV_API_DECL static? ev_default_loop_ptr?
TODO: EV_STANDALONE == NO_HASSEL (do not use clock_gettime in ev_standalone)
TODO: memory fences for clang
TODO: fix repeat=0 in http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#Be_smart_about_timeouts
@ -28,6 +27,8 @@ TODO: fix repeat=0 in http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#Be_sm
- fix #3 "be smart about timeouts" to not "deadlock" when
timeout == now, also improve the section overall.
- avoid "AVOIDING FINISHING BEFORE RETURNING" idiom.
- support new EV_API_STATIC mode to make all libev symbols
static.
4.04 Wed Feb 16 09:01:51 CET 2011
- fix two problems in the native win32 backend, where reuse of fd's

4
ev.c
View File

@ -1195,11 +1195,11 @@ typedef struct
#include "ev_wrap.h"
static struct ev_loop default_loop_struct;
struct ev_loop *ev_default_loop_ptr;
EV_API_DECL struct ev_loop *ev_default_loop_ptr = 0; /* needs to be initialised to make it a defintiino despite extern */
#else
ev_tstamp ev_rt_now;
EV_API_DECL ev_tstamp ev_rt_now = 0; /* needs to be initialised to make it a defintiino despite extern */
#define VAR(name,decl) static decl;
#include "ev_vars.h"
#undef VAR

160
ev.h
View File

@ -185,6 +185,12 @@ struct ev_loop;
# define EV_INLINE static
#endif
#ifdef EV_API_STATIC
# define EV_API_DECL static
#else
# define EV_API_DECL extern
#endif
/* EV_PROTOTYPES can be used to switch of prototype declarations */
#ifndef EV_PROTOTYPES
# define EV_PROTOTYPES 1
@ -508,15 +514,15 @@ enum {
};
#if EV_PROTOTYPES
int ev_version_major (void);
int ev_version_minor (void);
EV_API_DECL int ev_version_major (void);
EV_API_DECL int ev_version_minor (void);
unsigned int ev_supported_backends (void);
unsigned int ev_recommended_backends (void);
unsigned int ev_embeddable_backends (void);
EV_API_DECL unsigned int ev_supported_backends (void);
EV_API_DECL unsigned int ev_recommended_backends (void);
EV_API_DECL unsigned int ev_embeddable_backends (void);
ev_tstamp ev_time (void);
void ev_sleep (ev_tstamp delay); /* sleep for a while */
EV_API_DECL ev_tstamp ev_time (void);
EV_API_DECL void ev_sleep (ev_tstamp delay); /* sleep for a while */
/* Sets the allocation function to use, works like realloc.
* It is used to allocate and free memory.
@ -524,19 +530,21 @@ void ev_sleep (ev_tstamp delay); /* sleep for a while */
* or take some potentially destructive action.
* The default is your system realloc function.
*/
void ev_set_allocator (void *(*cb)(void *ptr, long size));
EV_API_DECL void ev_set_allocator (void *(*cb)(void *ptr, long size));
/* set the callback function to call on a
* retryable syscall error
* (such as failed select, poll, epoll_wait)
*/
void ev_set_syserr_cb (void (*cb)(const char *msg));
EV_API_DECL void ev_set_syserr_cb (void (*cb)(const char *msg));
#if EV_MULTIPLICITY
/* the default loop is the only one that handles signals and child watchers */
/* you can call this as often as you like */
struct ev_loop *ev_default_loop (unsigned int flags EV_CPP (= 0));
EV_API_DECL struct ev_loop *ev_default_loop (unsigned int flags EV_CPP (= 0));
EV_API_DECL struct ev_loop *ev_default_loop_ptr;
EV_INLINE struct ev_loop *
ev_default_loop_uc_ (void)
@ -553,19 +561,19 @@ ev_is_default_loop (EV_P)
}
/* create and destroy alternative loops that don't handle signals */
struct ev_loop *ev_loop_new (unsigned int flags EV_CPP (= 0));
EV_API_DECL struct ev_loop *ev_loop_new (unsigned int flags EV_CPP (= 0));
ev_tstamp ev_now (EV_P); /* time w.r.t. timers and the eventloop, updated after each poll */
EV_API_DECL ev_tstamp ev_now (EV_P); /* time w.r.t. timers and the eventloop, updated after each poll */
#else
int ev_default_loop (unsigned int flags EV_CPP (= 0)); /* returns true when successful */
EV_API_DECL int ev_default_loop (unsigned int flags EV_CPP (= 0)); /* returns true when successful */
EV_API_DECL ev_tstamp ev_rt_now;
EV_INLINE ev_tstamp
ev_now (void)
{
extern ev_tstamp ev_rt_now;
return ev_rt_now;
}
@ -579,23 +587,23 @@ ev_is_default_loop (void)
#endif /* multiplicity */
/* destroy event loops, also works for the default loop */
void ev_loop_destroy (EV_P);
EV_API_DECL void ev_loop_destroy (EV_P);
/* this needs to be called after fork, to duplicate the loop */
/* when you want to re-use it in the child */
/* you can call it in either the parent or the child */
/* you can actually call it at any time, anywhere :) */
void ev_loop_fork (EV_P);
EV_API_DECL void ev_loop_fork (EV_P);
unsigned int ev_backend (EV_P); /* backend in use by loop */
EV_API_DECL unsigned int ev_backend (EV_P); /* backend in use by loop */
void ev_now_update (EV_P); /* update event loop time */
EV_API_DECL void ev_now_update (EV_P); /* update event loop time */
#if EV_WALK_ENABLE
/* walk (almost) all watchers in the loop of a given type, invoking the */
/* callback on every such watcher. The callback might stop the watcher, */
/* but do nothing else with the loop */
void ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w));
EV_API_DECL void ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w));
#endif
#endif /* prototypes */
@ -614,45 +622,45 @@ enum {
};
#if EV_PROTOTYPES
void ev_run (EV_P_ int flags EV_CPP (= 0));
void ev_break (EV_P_ int how EV_CPP (= EVBREAK_ONE)); /* break out of the loop */
EV_API_DECL void ev_run (EV_P_ int flags EV_CPP (= 0));
EV_API_DECL void ev_break (EV_P_ int how EV_CPP (= EVBREAK_ONE)); /* break out of the loop */
/*
* ref/unref can be used to add or remove a refcount on the mainloop. every watcher
* keeps one reference. if you have a long-running watcher you never unregister that
* should not keep ev_loop from running, unref() after starting, and ref() before stopping.
*/
void ev_ref (EV_P);
void ev_unref (EV_P);
EV_API_DECL void ev_ref (EV_P);
EV_API_DECL void ev_unref (EV_P);
/*
* convenience function, wait for a single event, without registering an event watcher
* if timeout is < 0, do wait indefinitely
*/
void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg);
EV_API_DECL void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg);
# if EV_FEATURE_API
unsigned int ev_iteration (EV_P); /* number of loop iterations */
unsigned int ev_depth (EV_P); /* #ev_loop enters - #ev_loop leaves */
void ev_verify (EV_P); /* abort if loop data corrupted */
EV_API_DECL unsigned int ev_iteration (EV_P); /* number of loop iterations */
EV_API_DECL unsigned int ev_depth (EV_P); /* #ev_loop enters - #ev_loop leaves */
EV_API_DECL void ev_verify (EV_P); /* abort if loop data corrupted */
void ev_set_io_collect_interval (EV_P_ ev_tstamp interval); /* sleep at least this time, default 0 */
void ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval); /* sleep at least this time, default 0 */
EV_API_DECL void ev_set_io_collect_interval (EV_P_ ev_tstamp interval); /* sleep at least this time, default 0 */
EV_API_DECL void ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval); /* sleep at least this time, default 0 */
/* advanced stuff for threading etc. support, see docs */
void ev_set_userdata (EV_P_ void *data);
void *ev_userdata (EV_P);
void ev_set_invoke_pending_cb (EV_P_ void (*invoke_pending_cb)(EV_P));
void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P), void (*acquire)(EV_P));
EV_API_DECL void ev_set_userdata (EV_P_ void *data);
EV_API_DECL void *ev_userdata (EV_P);
EV_API_DECL void ev_set_invoke_pending_cb (EV_P_ void (*invoke_pending_cb)(EV_P));
EV_API_DECL void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P), void (*acquire)(EV_P));
unsigned int ev_pending_count (EV_P); /* number of pending events, if any */
void ev_invoke_pending (EV_P); /* invoke all pending watchers */
EV_API_DECL unsigned int ev_pending_count (EV_P); /* number of pending events, if any */
EV_API_DECL void ev_invoke_pending (EV_P); /* invoke all pending watchers */
/*
* stop/start the timer handling.
*/
void ev_suspend (EV_P);
void ev_resume (EV_P);
EV_API_DECL void ev_suspend (EV_P);
EV_API_DECL void ev_resume (EV_P);
#endif
#endif
@ -719,85 +727,85 @@ void ev_resume (EV_P);
/* feeds an event into a watcher as if the event actually occurred */
/* accepts any ev_watcher type */
void ev_feed_event (EV_P_ void *w, int revents);
void ev_feed_fd_event (EV_P_ int fd, int revents);
EV_API_DECL void ev_feed_event (EV_P_ void *w, int revents);
EV_API_DECL void ev_feed_fd_event (EV_P_ int fd, int revents);
#if EV_SIGNAL_ENABLE
void ev_feed_signal (int signum);
void ev_feed_signal_event (EV_P_ int signum);
EV_API_DECL void ev_feed_signal (int signum);
EV_API_DECL void ev_feed_signal_event (EV_P_ int signum);
#endif
void ev_invoke (EV_P_ void *w, int revents);
int ev_clear_pending (EV_P_ void *w);
EV_API_DECL void ev_invoke (EV_P_ void *w, int revents);
EV_API_DECL int ev_clear_pending (EV_P_ void *w);
void ev_io_start (EV_P_ ev_io *w);
void ev_io_stop (EV_P_ ev_io *w);
EV_API_DECL void ev_io_start (EV_P_ ev_io *w);
EV_API_DECL void ev_io_stop (EV_P_ ev_io *w);
void ev_timer_start (EV_P_ ev_timer *w);
void ev_timer_stop (EV_P_ ev_timer *w);
EV_API_DECL void ev_timer_start (EV_P_ ev_timer *w);
EV_API_DECL void ev_timer_stop (EV_P_ ev_timer *w);
/* stops if active and no repeat, restarts if active and repeating, starts if inactive and repeating */
void ev_timer_again (EV_P_ ev_timer *w);
EV_API_DECL void ev_timer_again (EV_P_ ev_timer *w);
/* return remaining time */
ev_tstamp ev_timer_remaining (EV_P_ ev_timer *w);
EV_API_DECL ev_tstamp ev_timer_remaining (EV_P_ ev_timer *w);
#if EV_PERIODIC_ENABLE
void ev_periodic_start (EV_P_ ev_periodic *w);
void ev_periodic_stop (EV_P_ ev_periodic *w);
void ev_periodic_again (EV_P_ ev_periodic *w);
EV_API_DECL void ev_periodic_start (EV_P_ ev_periodic *w);
EV_API_DECL void ev_periodic_stop (EV_P_ ev_periodic *w);
EV_API_DECL void ev_periodic_again (EV_P_ ev_periodic *w);
#endif
/* only supported in the default loop */
#if EV_SIGNAL_ENABLE
void ev_signal_start (EV_P_ ev_signal *w);
void ev_signal_stop (EV_P_ ev_signal *w);
EV_API_DECL void ev_signal_start (EV_P_ ev_signal *w);
EV_API_DECL void ev_signal_stop (EV_P_ ev_signal *w);
#endif
/* only supported in the default loop */
# if EV_CHILD_ENABLE
void ev_child_start (EV_P_ ev_child *w);
void ev_child_stop (EV_P_ ev_child *w);
EV_API_DECL void ev_child_start (EV_P_ ev_child *w);
EV_API_DECL void ev_child_stop (EV_P_ ev_child *w);
# endif
# if EV_STAT_ENABLE
void ev_stat_start (EV_P_ ev_stat *w);
void ev_stat_stop (EV_P_ ev_stat *w);
void ev_stat_stat (EV_P_ ev_stat *w);
EV_API_DECL void ev_stat_start (EV_P_ ev_stat *w);
EV_API_DECL void ev_stat_stop (EV_P_ ev_stat *w);
EV_API_DECL void ev_stat_stat (EV_P_ ev_stat *w);
# endif
# if EV_IDLE_ENABLE
void ev_idle_start (EV_P_ ev_idle *w);
void ev_idle_stop (EV_P_ ev_idle *w);
EV_API_DECL void ev_idle_start (EV_P_ ev_idle *w);
EV_API_DECL void ev_idle_stop (EV_P_ ev_idle *w);
# endif
#if EV_PREPARE_ENABLE
void ev_prepare_start (EV_P_ ev_prepare *w);
void ev_prepare_stop (EV_P_ ev_prepare *w);
EV_API_DECL void ev_prepare_start (EV_P_ ev_prepare *w);
EV_API_DECL void ev_prepare_stop (EV_P_ ev_prepare *w);
#endif
#if EV_CHECK_ENABLE
void ev_check_start (EV_P_ ev_check *w);
void ev_check_stop (EV_P_ ev_check *w);
EV_API_DECL void ev_check_start (EV_P_ ev_check *w);
EV_API_DECL void ev_check_stop (EV_P_ ev_check *w);
#endif
# if EV_FORK_ENABLE
void ev_fork_start (EV_P_ ev_fork *w);
void ev_fork_stop (EV_P_ ev_fork *w);
EV_API_DECL void ev_fork_start (EV_P_ ev_fork *w);
EV_API_DECL void ev_fork_stop (EV_P_ ev_fork *w);
# endif
# if EV_CLEANUP_ENABLE
void ev_cleanup_start (EV_P_ ev_cleanup *w);
void ev_cleanup_stop (EV_P_ ev_cleanup *w);
EV_API_DECL void ev_cleanup_start (EV_P_ ev_cleanup *w);
EV_API_DECL void ev_cleanup_stop (EV_P_ ev_cleanup *w);
# endif
# if EV_EMBED_ENABLE
/* only supported when loop to be embedded is in fact embeddable */
void ev_embed_start (EV_P_ ev_embed *w);
void ev_embed_stop (EV_P_ ev_embed *w);
void ev_embed_sweep (EV_P_ ev_embed *w);
EV_API_DECL void ev_embed_start (EV_P_ ev_embed *w);
EV_API_DECL void ev_embed_stop (EV_P_ ev_embed *w);
EV_API_DECL void ev_embed_sweep (EV_P_ ev_embed *w);
# endif
# if EV_ASYNC_ENABLE
void ev_async_start (EV_P_ ev_async *w);
void ev_async_stop (EV_P_ ev_async *w);
void ev_async_send (EV_P_ ev_async *w);
EV_API_DECL void ev_async_start (EV_P_ ev_async *w);
EV_API_DECL void ev_async_stop (EV_P_ ev_async *w);
EV_API_DECL void ev_async_send (EV_P_ ev_async *w);
# endif
#if EV_COMPAT3

11
ev.pod
View File

@ -4654,6 +4654,17 @@ when you use C<-Wl,--gc-sections -ffunction-sections>) functions unused by
your program might be left out as well - a binary starting a timer and an
I/O watcher then might come out at only 5Kb.
=item EV_API_STATIC
If this symbol is defined (by default it is not), then all identifiers
will have static linkage. This means that libev will not export any
identifiers, and you cannot link against libev anymore. This can be useful
when you embed libev, only want to use libev functions in a single file,
and do not want its identifiers to be visible.
To use this, define C<EV_API_STATIC> and include F<ev.c> in the file that
wants to use libev.
=item EV_AVOID_STDIO
If this is set to C<1> at compiletime, then libev will avoid using stdio