*** empty log message ***

This commit is contained in:
Marc Alexander Lehmann 2012-04-02 23:14:40 +00:00
parent 04fc56741f
commit 9c9c782fc5
7 changed files with 68 additions and 24 deletions

View File

@ -7,7 +7,11 @@ TODO: document WSA_EV_USE_SOCKET in win32 part
TODO: ^ OR use WSASend/WSARecv on the handle, which always works
TODO: use __OPTIMIZE__ or __OPTIMIZE_SIZE__?
TODO: Jeff Davey libev patch
- fix event_base_loop return code, add event_get_callback, event_base_new,
event_base_get_method calls to improve libevent 1.x emulation and add
some libevent 2.x funcitonality (based on a patch by Jeff Davey).
- ev_run now returns a boolean status (true meaning watchers are
still active).
- ev_once: undef EV_ERROR in ev_kqueue.c, to avoid clashing with
libev's EV_ERROR (reported by 191919).
- (ecb) add memory fence support for xlC (Darin McBride).

22
ev.3
View File

@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "LIBEV 3"
.TH LIBEV 3 "2012-03-23" "libev-4.11" "libev - high performance full featured event loop"
.TH LIBEV 3 "2012-04-03" "libev-4.11" "libev - high performance full featured event loop"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
@ -687,9 +687,9 @@ It scales in the same way as the epoll backend, but the interface to the
kernel is more efficient (which says nothing about its actual speed, of
course). While stopping, setting and starting an I/O watcher does never
cause an extra system call as with \f(CW\*(C`EVBACKEND_EPOLL\*(C'\fR, it still adds up to
two event changes per incident. Support for \f(CW\*(C`fork ()\*(C'\fR is very bad (but
sane, unlike epoll) and it drops fds silently in similarly hard-to-detect
cases
two event changes per incident. Support for \f(CW\*(C`fork ()\*(C'\fR is very bad (you
might have to leak fd's on fork, but it's more sane than epoll) and it
drops fds silently in similarly hard-to-detect cases
.Sp
This backend usually performs well under most conditions.
.Sp
@ -911,18 +911,22 @@ without a previous call to \f(CW\*(C`ev_suspend\*(C'\fR.
.Sp
Calling \f(CW\*(C`ev_suspend\*(C'\fR/\f(CW\*(C`ev_resume\*(C'\fR has the side effect of updating the
event loop time (see \f(CW\*(C`ev_now_update\*(C'\fR).
.IP "ev_run (loop, int flags)" 4
.IX Item "ev_run (loop, int flags)"
.IP "bool ev_run (loop, int flags)" 4
.IX Item "bool ev_run (loop, int flags)"
Finally, this is it, the event handler. This function usually is called
after you have initialised all your watchers and you want to start
handling events. It will ask the operating system for any new events, call
the watcher callbacks, an then repeat the whole process indefinitely: This
the watcher callbacks, and then repeat the whole process indefinitely: This
is why event loops are called \fIloops\fR.
.Sp
If the flags argument is specified as \f(CW0\fR, it will keep handling events
until either no event watchers are active anymore or \f(CW\*(C`ev_break\*(C'\fR was
called.
.Sp
The return value is false if there are no more active watchers (which
usually means \*(L"all jobs done\*(R" or \*(L"deadlock\*(R"), and true in all other cases
(which usually means " you should call \f(CW\*(C`ev_run\*(C'\fR again").
.Sp
Please note that an explicit \f(CW\*(C`ev_break\*(C'\fR is usually better than
relying on all watchers to be stopped when deciding when a program has
finished (especially in interactive programs), but having a program
@ -930,8 +934,8 @@ that automatically loops as long as it has to and no longer by virtue
of relying on its watchers stopping correctly, that is truly a thing of
beauty.
.Sp
This function is also \fImostly\fR exception-safe \- you can break out of
a \f(CW\*(C`ev_run\*(C'\fR call by calling \f(CW\*(C`longjmp\*(C'\fR in a callback, throwing a \*(C+
This function is \fImostly\fR exception-safe \- you can break out of a
\&\f(CW\*(C`ev_run\*(C'\fR call by calling \f(CW\*(C`longjmp\*(C'\fR in a callback, throwing a \*(C+
exception and so on. This does not decrement the \f(CW\*(C`ev_depth\*(C'\fR value, nor
will it clear any outstanding \f(CW\*(C`EVBREAK_ONE\*(C'\fR breaks.
.Sp

6
ev.c
View File

@ -1,7 +1,7 @@
/*
* libev event processing core, watcher management
*
* Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
* Copyright (c) 2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann <libev@schmorp.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modifica-
@ -2932,7 +2932,7 @@ time_update (EV_P_ ev_tstamp max_block)
}
}
void
int
ev_run (EV_P_ int flags)
{
#if EV_FEATURE_API
@ -3099,6 +3099,8 @@ ev_run (EV_P_ int flags)
#if EV_FEATURE_API
--loop_depth;
#endif
return activecnt;
}
void

2
ev.h
View File

@ -624,7 +624,7 @@ enum {
};
#if EV_PROTOTYPES
EV_API_DECL void ev_run (EV_P_ int flags EV_CPP (= 0));
EV_API_DECL int 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 */
/*

12
ev.pod
View File

@ -794,18 +794,22 @@ without a previous call to C<ev_suspend>.
Calling C<ev_suspend>/C<ev_resume> has the side effect of updating the
event loop time (see C<ev_now_update>).
=item ev_run (loop, int flags)
=item bool ev_run (loop, int flags)
Finally, this is it, the event handler. This function usually is called
after you have initialised all your watchers and you want to start
handling events. It will ask the operating system for any new events, call
the watcher callbacks, an then repeat the whole process indefinitely: This
the watcher callbacks, and then repeat the whole process indefinitely: This
is why event loops are called I<loops>.
If the flags argument is specified as C<0>, it will keep handling events
until either no event watchers are active anymore or C<ev_break> was
called.
The return value is false if there are no more active watchers (which
usually means "all jobs done" or "deadlock"), and true in all other cases
(which usually means " you should call C<ev_run> again").
Please note that an explicit C<ev_break> is usually better than
relying on all watchers to be stopped when deciding when a program has
finished (especially in interactive programs), but having a program
@ -813,8 +817,8 @@ that automatically loops as long as it has to and no longer by virtue
of relying on its watchers stopping correctly, that is truly a thing of
beauty.
This function is also I<mostly> exception-safe - you can break out of
a C<ev_run> call by calling C<longjmp> in a callback, throwing a C++
This function is I<mostly> exception-safe - you can break out of a
C<ev_run> call by calling C<longjmp> in a callback, throwing a C++
exception and so on. This does not decrement the C<ev_depth> value, nor
will it clear any outstanding C<EVBREAK_ONE> breaks.

33
event.c
View File

@ -78,13 +78,15 @@ ev_tv_get (struct timeval *tv)
#define EVENT_STRINGIFY(s) # s
#define EVENT_VERSION(a,b) EVENT_STRINGIFY (a) "." EVENT_STRINGIFY (b)
const char *event_get_version (void)
const char *
event_get_version (void)
{
/* returns ABI, not API or library, version */
return EVENT_VERSION (EV_VERSION_MAJOR, EV_VERSION_MINOR);
}
const char *event_get_method (void)
const char *
event_get_method (void)
{
return "libev";
}
@ -105,6 +107,23 @@ void *event_init (void)
return ev_x_cur;
}
const char *
event_base_get_method (const struct event_base *base)
{
return "libev";
}
struct event_base *
event_base_new (void)
{
#if EV_MULTIPLICITY
return (struct event_base *)ev_loop_new (EVFLAG_AUTO);
#else
assert (("libev: multiple event bases not supported when not compiled with EV_MULTIPLICITY"));
return NULL;
#endif
}
void event_base_free (struct event_base *base)
{
dLOOPbase;
@ -137,6 +156,12 @@ int event_loopexit (struct timeval *tv)
return event_base_loopexit (ev_x_cur, tv);
}
event_callback_fn event_get_callback
(const struct event *ev)
{
return ev->ev_callback;
}
static void
ev_x_cb (struct event *ev, int revents)
{
@ -332,9 +357,7 @@ int event_base_loop (struct event_base *base, int flags)
{
dLOOPbase;
ev_run (EV_A_ flags);
return 0;
return !ev_run (EV_A_ flags);
}
int event_base_dispatch (struct event_base *base)

11
event.h
View File

@ -1,7 +1,7 @@
/*
* libevent compatibility header, only core events supported
*
* Copyright (c) 2007,2008,2010 Marc Alexander Lehmann <libev@schmorp.de>
* Copyright (c) 2007,2008,2010,2012 Marc Alexander Lehmann <libev@schmorp.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modifica-
@ -75,6 +75,8 @@ struct event_base;
#define EVLIST_INTERNAL 0x10
#define EVLIST_INIT 0x80
typedef void (*event_callback_fn)(int, short, void *);
struct event
{
/* libev watchers we map onto */
@ -86,7 +88,7 @@ struct event
/* compatibility slots */
struct event_base *ev_base;
void (*ev_callback)(int, short, void *arg);
event_callback_fn ev_callback;
void *ev_arg;
int ev_fd;
int ev_pri;
@ -95,9 +97,12 @@ struct event
short ev_events;
};
event_callback_fn event_get_callback (const struct event *ev);
#define EV_READ EV_READ
#define EV_WRITE EV_WRITE
#define EV_PERSIST 0x10
#define EV_ET 0x20 /* nop */
#define EVENT_SIGNAL(ev) ((int) (ev)->ev_fd)
#define EVENT_FD(ev) ((int) (ev)->ev_fd)
@ -152,6 +157,8 @@ int event_pending (struct event *ev, short, struct timeval *tv);
int event_priority_init (int npri);
int event_priority_set (struct event *ev, int pri);
struct event_base *event_base_new (void);
const char *event_base_get_method (const struct event_base *);
int event_base_set (struct event_base *base, struct event *ev);
int event_base_loop (struct event_base *base, int);
int event_base_loopexit (struct event_base *base, struct timeval *tv);