mirror of /home/gitosis/repositories/libev.git
better error handling
parent
06cd0f8c41
commit
66df0f5347
85
ev.c
85
ev.c
|
@ -155,6 +155,51 @@ volatile double SIGFPE_REQ = 0.0f;
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void (*syserr_cb)(void);
|
||||
|
||||
void ev_set_syserr_cb (void (*cb)(void))
|
||||
{
|
||||
syserr_cb = cb;
|
||||
}
|
||||
|
||||
static void
|
||||
syserr (void)
|
||||
{
|
||||
if (syserr_cb)
|
||||
syserr_cb ();
|
||||
else
|
||||
{
|
||||
perror ("libev");
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
static void *(*alloc)(void *ptr, long size);
|
||||
|
||||
void ev_set_allocator (void *(*cb)(void *ptr, long size))
|
||||
{
|
||||
alloc = cb;
|
||||
}
|
||||
|
||||
static void *
|
||||
ev_realloc (void *ptr, long size)
|
||||
{
|
||||
ptr = alloc ? alloc (ptr, size) : realloc (ptr, size);
|
||||
|
||||
if (!ptr && size)
|
||||
{
|
||||
fprintf (stderr, "libev: cannot allocate %ld bytes, aborting.", size);
|
||||
abort ();
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#define ev_malloc(size) ev_realloc (0, (size))
|
||||
#define ev_free(ptr) ev_realloc ((ptr), 0)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WL head;
|
||||
|
@ -225,31 +270,31 @@ ev_now (EV_P)
|
|||
|
||||
#define array_roundsize(base,n) ((n) | 4 & ~3)
|
||||
|
||||
#define array_needsize(base,cur,cnt,init) \
|
||||
if (expect_false ((cnt) > cur)) \
|
||||
{ \
|
||||
int newcnt = cur; \
|
||||
do \
|
||||
{ \
|
||||
newcnt = array_roundsize (base, newcnt << 1); \
|
||||
} \
|
||||
while ((cnt) > newcnt); \
|
||||
\
|
||||
base = realloc (base, sizeof (*base) * (newcnt)); \
|
||||
init (base + cur, newcnt - cur); \
|
||||
cur = newcnt; \
|
||||
#define array_needsize(base,cur,cnt,init) \
|
||||
if (expect_false ((cnt) > cur)) \
|
||||
{ \
|
||||
int newcnt = cur; \
|
||||
do \
|
||||
{ \
|
||||
newcnt = array_roundsize (base, newcnt << 1); \
|
||||
} \
|
||||
while ((cnt) > newcnt); \
|
||||
\
|
||||
base = ev_realloc (base, sizeof (*base) * (newcnt)); \
|
||||
init (base + cur, newcnt - cur); \
|
||||
cur = newcnt; \
|
||||
}
|
||||
|
||||
#define array_slim(stem) \
|
||||
if (stem ## max < array_roundsize (stem ## cnt >> 2)) \
|
||||
{ \
|
||||
stem ## max = array_roundsize (stem ## cnt >> 1); \
|
||||
base = realloc (base, sizeof (*base) * (stem ## max)); \
|
||||
base = ev_realloc (base, sizeof (*base) * (stem ## max)); \
|
||||
fprintf (stderr, "slimmed down " # stem " to %d\n", stem ## max);/*D*/\
|
||||
}
|
||||
|
||||
#define array_free(stem, idx) \
|
||||
free (stem ## s idx); stem ## cnt idx = stem ## max idx = 0;
|
||||
ev_free (stem ## s idx); stem ## cnt idx = stem ## max idx = 0;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
@ -704,7 +749,9 @@ loop_fork (EV_P)
|
|||
struct ev_loop *
|
||||
ev_loop_new (int methods)
|
||||
{
|
||||
struct ev_loop *loop = (struct ev_loop *)calloc (1, sizeof (struct ev_loop));
|
||||
struct ev_loop *loop = (struct ev_loop *)ev_malloc (sizeof (struct ev_loop));
|
||||
|
||||
memset (loop, 0, sizeof (struct ev_loop));
|
||||
|
||||
loop_init (EV_A_ methods);
|
||||
|
||||
|
@ -718,7 +765,7 @@ void
|
|||
ev_loop_destroy (EV_P)
|
||||
{
|
||||
loop_destroy (EV_A);
|
||||
free (loop);
|
||||
ev_free (loop);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1397,7 +1444,7 @@ once_cb (EV_P_ struct ev_once *once, int revents)
|
|||
|
||||
ev_io_stop (EV_A_ &once->io);
|
||||
ev_timer_stop (EV_A_ &once->to);
|
||||
free (once);
|
||||
ev_free (once);
|
||||
|
||||
cb (revents, arg);
|
||||
}
|
||||
|
@ -1417,7 +1464,7 @@ once_cb_to (EV_P_ struct ev_timer *w, int revents)
|
|||
void
|
||||
ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg)
|
||||
{
|
||||
struct ev_once *once = malloc (sizeof (struct ev_once));
|
||||
struct ev_once *once = ev_malloc (sizeof (struct ev_once));
|
||||
|
||||
if (!once)
|
||||
cb (EV_ERROR | EV_READ | EV_WRITE | EV_TIMEOUT, arg);
|
||||
|
|
14
ev.h
14
ev.h
|
@ -229,6 +229,20 @@ int ev_version_minor (void);
|
|||
|
||||
ev_tstamp ev_time (void);
|
||||
|
||||
/* Sets the allocation function to use, works like realloc.
|
||||
* It is used to allocate and free memory.
|
||||
* If it returns zero when memory needs to be allocated, the library might abort
|
||||
* or take some potentially destructive action.
|
||||
* The default is your system realloc function.
|
||||
*/
|
||||
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)(void));
|
||||
|
||||
# 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 */
|
||||
|
|
17
ev_epoll.c
17
ev_epoll.c
|
@ -51,11 +51,16 @@ epoll_modify (EV_P_ int fd, int oev, int nev)
|
|||
static void
|
||||
epoll_poll (EV_P_ ev_tstamp timeout)
|
||||
{
|
||||
int eventcnt = epoll_wait (epoll_fd, epoll_events, epoll_eventmax, ceil (timeout * 1000.));
|
||||
int i;
|
||||
int eventcnt = epoll_wait (epoll_fd, epoll_events, epoll_eventmax, ceil (timeout * 1000.));
|
||||
|
||||
if (eventcnt < 0)
|
||||
return;
|
||||
{
|
||||
if (errno != EINTR)
|
||||
syserr ();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < eventcnt; ++i)
|
||||
fd_event (
|
||||
|
@ -68,9 +73,9 @@ epoll_poll (EV_P_ ev_tstamp timeout)
|
|||
/* if the receive array was full, increase its size */
|
||||
if (expect_false (eventcnt == epoll_eventmax))
|
||||
{
|
||||
free (epoll_events);
|
||||
ev_free (epoll_events);
|
||||
epoll_eventmax = array_roundsize (epoll_events, epoll_eventmax << 1);
|
||||
epoll_events = malloc (sizeof (struct epoll_event) * epoll_eventmax);
|
||||
epoll_events = ev_malloc (sizeof (struct epoll_event) * epoll_eventmax);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,7 +94,7 @@ epoll_init (EV_P_ int flags)
|
|||
method_poll = epoll_poll;
|
||||
|
||||
epoll_eventmax = 64; /* intiial number of events receivable per poll */
|
||||
epoll_events = malloc (sizeof (struct epoll_event) * epoll_eventmax);
|
||||
epoll_events = ev_malloc (sizeof (struct epoll_event) * epoll_eventmax);
|
||||
|
||||
return EVMETHOD_EPOLL;
|
||||
}
|
||||
|
@ -99,7 +104,7 @@ epoll_destroy (EV_P)
|
|||
{
|
||||
close (epoll_fd);
|
||||
|
||||
free (epoll_events);
|
||||
ev_free (epoll_events);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
17
ev_kqueue.c
17
ev_kqueue.c
|
@ -85,7 +85,12 @@ kqueue_poll (EV_P_ ev_tstamp timeout)
|
|||
kqueue_changecnt = 0;
|
||||
|
||||
if (res < 0)
|
||||
return;
|
||||
{
|
||||
if (errno != EINTR)
|
||||
syserr ();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < res; ++i)
|
||||
{
|
||||
|
@ -118,9 +123,9 @@ kqueue_poll (EV_P_ ev_tstamp timeout)
|
|||
|
||||
if (expect_false (res == kqueue_eventmax))
|
||||
{
|
||||
free (kqueue_events);
|
||||
ev_free (kqueue_events);
|
||||
kqueue_eventmax = array_roundsize (kqueue_events, kqueue_eventmax << 1);
|
||||
kqueue_events = malloc (sizeof (struct kevent) * kqueue_eventmax);
|
||||
kqueue_events = ev_malloc (sizeof (struct kevent) * kqueue_eventmax);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,7 +164,7 @@ kqueue_init (EV_P_ int flags)
|
|||
method_poll = kqueue_poll;
|
||||
|
||||
kqueue_eventmax = 64; /* intiial number of events receivable per poll */
|
||||
kqueue_events = malloc (sizeof (struct kevent) * kqueue_eventmax);
|
||||
kqueue_events = ev_malloc (sizeof (struct kevent) * kqueue_eventmax);
|
||||
|
||||
kqueue_changes = 0;
|
||||
kqueue_changemax = 0;
|
||||
|
@ -173,8 +178,8 @@ kqueue_destroy (EV_P)
|
|||
{
|
||||
close (kqueue_fd);
|
||||
|
||||
free (kqueue_events);
|
||||
free (kqueue_changes);
|
||||
ev_free (kqueue_events);
|
||||
ev_free (kqueue_changes);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
33
ev_poll.c
33
ev_poll.c
|
@ -75,27 +75,28 @@ poll_modify (EV_P_ int fd, int oev, int nev)
|
|||
static void
|
||||
poll_poll (EV_P_ ev_tstamp timeout)
|
||||
{
|
||||
int i;
|
||||
int res = poll (polls, pollcnt, ceil (timeout * 1000.));
|
||||
|
||||
if (res > 0)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pollcnt; ++i)
|
||||
fd_event (
|
||||
EV_A_
|
||||
polls [i].fd,
|
||||
(polls [i].revents & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0)
|
||||
| (polls [i].revents & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0)
|
||||
);
|
||||
}
|
||||
else if (res < 0)
|
||||
if (res < 0)
|
||||
{
|
||||
if (errno == EBADF)
|
||||
fd_ebadf (EV_A);
|
||||
else if (errno == ENOMEM)
|
||||
else if (errno == ENOMEM && !syserr_cb)
|
||||
fd_enomem (EV_A);
|
||||
else if (errno != EINTR)
|
||||
syserr ();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < pollcnt; ++i)
|
||||
fd_event (
|
||||
EV_A_
|
||||
polls [i].fd,
|
||||
(polls [i].revents & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0)
|
||||
| (polls [i].revents & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0)
|
||||
);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -114,6 +115,6 @@ poll_init (EV_P_ int flags)
|
|||
static void
|
||||
poll_destroy (EV_P)
|
||||
{
|
||||
free (pollidxs);
|
||||
free (polls);
|
||||
ev_free (pollidxs);
|
||||
ev_free (polls);
|
||||
}
|
||||
|
|
75
ev_select.c
75
ev_select.c
|
@ -55,10 +55,10 @@ select_modify (EV_P_ int fd, int oev, int nev)
|
|||
{
|
||||
int new_max = (fd >> 5) + 1;
|
||||
|
||||
vec_ri = (unsigned char *)realloc (vec_ri, new_max * 4);
|
||||
vec_ro = (unsigned char *)realloc (vec_ro, new_max * 4); /* could free/malloc */
|
||||
vec_wi = (unsigned char *)realloc (vec_wi, new_max * 4);
|
||||
vec_wo = (unsigned char *)realloc (vec_wo, new_max * 4); /* could free/malloc */
|
||||
vec_ri = (unsigned char *)ev_realloc (vec_ri, new_max * 4);
|
||||
vec_ro = (unsigned char *)ev_realloc (vec_ro, new_max * 4); /* could free/malloc */
|
||||
vec_wi = (unsigned char *)ev_realloc (vec_wi, new_max * 4);
|
||||
vec_wo = (unsigned char *)ev_realloc (vec_wo, new_max * 4); /* could free/malloc */
|
||||
|
||||
for (; vec_max < new_max; ++vec_max)
|
||||
((uint32_t *)vec_ri)[vec_max] =
|
||||
|
@ -77,6 +77,7 @@ select_modify (EV_P_ int fd, int oev, int nev)
|
|||
static void
|
||||
select_poll (EV_P_ ev_tstamp timeout)
|
||||
{
|
||||
int word, offs;
|
||||
struct timeval tv;
|
||||
int res;
|
||||
|
||||
|
@ -88,39 +89,39 @@ select_poll (EV_P_ ev_tstamp timeout)
|
|||
|
||||
res = select (vec_max * 32, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv);
|
||||
|
||||
if (res > 0)
|
||||
{
|
||||
int word, offs;
|
||||
|
||||
for (word = vec_max; word--; )
|
||||
{
|
||||
if (((uint32_t *)vec_ro) [word] | ((uint32_t *)vec_wo) [word])
|
||||
for (offs = 4; offs--; )
|
||||
{
|
||||
int idx = word * 4 + offs;
|
||||
unsigned char byte_r = vec_ro [idx];
|
||||
unsigned char byte_w = vec_wo [idx];
|
||||
int bit;
|
||||
|
||||
if (byte_r | byte_w)
|
||||
for (bit = 8; bit--; )
|
||||
{
|
||||
int events = 0;
|
||||
events |= byte_r & (1 << bit) ? EV_READ : 0;
|
||||
events |= byte_w & (1 << bit) ? EV_WRITE : 0;
|
||||
|
||||
if (events)
|
||||
fd_event (EV_A_ idx * 8 + bit, events);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (res < 0)
|
||||
if (res < 0)
|
||||
{
|
||||
if (errno == EBADF)
|
||||
fd_ebadf (EV_A);
|
||||
else if (errno == ENOMEM)
|
||||
else if (errno == ENOMEM && !syserr_cb)
|
||||
fd_enomem (EV_A);
|
||||
else if (errno != EINTR)
|
||||
syserr ();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (word = vec_max; word--; )
|
||||
{
|
||||
if (((uint32_t *)vec_ro) [word] | ((uint32_t *)vec_wo) [word])
|
||||
for (offs = 4; offs--; )
|
||||
{
|
||||
int idx = word * 4 + offs;
|
||||
unsigned char byte_r = vec_ro [idx];
|
||||
unsigned char byte_w = vec_wo [idx];
|
||||
int bit;
|
||||
|
||||
if (byte_r | byte_w)
|
||||
for (bit = 8; bit--; )
|
||||
{
|
||||
int events = 0;
|
||||
events |= byte_r & (1 << bit) ? EV_READ : 0;
|
||||
events |= byte_w & (1 << bit) ? EV_WRITE : 0;
|
||||
|
||||
if (events)
|
||||
fd_event (EV_A_ idx * 8 + bit, events);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,10 +144,10 @@ select_init (EV_P_ int flags)
|
|||
static void
|
||||
select_destroy (EV_P)
|
||||
{
|
||||
free (vec_ri);
|
||||
free (vec_ro);
|
||||
free (vec_wi);
|
||||
free (vec_wo);
|
||||
ev_free (vec_ri);
|
||||
ev_free (vec_ro);
|
||||
ev_free (vec_wi);
|
||||
ev_free (vec_wo);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue