diff options
-rw-r--r-- | lib/libevent/buffer.c | 51 | ||||
-rw-r--r-- | lib/libevent/evbuffer.c | 9 | ||||
-rw-r--r-- | lib/libevent/event.3 | 14 | ||||
-rw-r--r-- | lib/libevent/event.c | 5 | ||||
-rw-r--r-- | lib/libevent/event.h | 5 | ||||
-rw-r--r-- | lib/libevent/kqueue.c | 3 | ||||
-rw-r--r-- | lib/libevent/log.c | 15 | ||||
-rw-r--r-- | lib/libevent/poll.c | 101 |
8 files changed, 160 insertions, 43 deletions
diff --git a/lib/libevent/buffer.c b/lib/libevent/buffer.c index a072e7d51ee..446f1d9ba2d 100644 --- a/lib/libevent/buffer.c +++ b/lib/libevent/buffer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: buffer.c,v 1.4 2005/04/22 00:56:25 brad Exp $ */ +/* $OpenBSD: buffer.c,v 1.5 2005/05/04 03:17:48 brad Exp $ */ /* * Copyright (c) 2002, 2003 Niels Provos <provos@citi.umich.edu> @@ -168,7 +168,7 @@ end: int evbuffer_remove(struct evbuffer *buf, void *data, size_t datlen) { - int nread = datlen; + size_t nread = datlen; if (nread >= buf->off) nread = buf->off; @@ -178,6 +178,53 @@ evbuffer_remove(struct evbuffer *buf, void *data, size_t datlen) return (nread); } +/* + * Reads a line terminated by either '\r\n', '\n\r' or '\r' or '\n'. + * The returned buffer needs to be freed by the called. + */ + +char * +evbuffer_readline(struct evbuffer *buffer) +{ + char *data = EVBUFFER_DATA(buffer); + size_t len = EVBUFFER_LENGTH(buffer); + char *line; + int i; + + for (i = 0; i < len; i++) { + if (data[i] == '\r' || data[i] == '\n') + break; + } + + if (i == len) + return (NULL); + + if ((line = malloc(i + 1)) == NULL) { + fprintf(stderr, "%s: out of memory\n", __func__); + evbuffer_drain(buffer, i); + return (NULL); + } + + memcpy(line, data, i); + line[i] = '\0'; + + /* + * Some protocols terminate a line with '\r\n', so check for + * that, too. + */ + if ( i < len - 1 ) { + char fch = data[i], sch = data[i+1]; + + /* Drain one more character if needed */ + if ( (sch == '\r' || sch == '\n') && sch != fch ) + i += 1; + } + + evbuffer_drain(buffer, i + 1); + + return (line); +} + /* Adds data to an event buffer */ static inline void diff --git a/lib/libevent/evbuffer.c b/lib/libevent/evbuffer.c index 4a2d85303e5..e886b405145 100644 --- a/lib/libevent/evbuffer.c +++ b/lib/libevent/evbuffer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: evbuffer.c,v 1.4 2005/04/22 00:56:25 brad Exp $ */ +/* $OpenBSD: evbuffer.c,v 1.5 2005/05/04 03:17:48 brad Exp $ */ /* * Copyright (c) 2002-2004 Niels Provos <provos@citi.umich.edu> @@ -47,6 +47,11 @@ #include "event.h" +/* prototypes */ + +void bufferevent_setwatermark(struct bufferevent *, short, size_t, size_t); +void bufferevent_read_pressure_cb(struct evbuffer *, size_t, size_t, void *); + static int bufferevent_add(struct event *ev, int timeout) { @@ -239,6 +244,8 @@ bufferevent_priority_set(struct bufferevent *bufev, int priority) return (0); } +/* Closing the file descriptor is the responsibility of the caller */ + void bufferevent_free(struct bufferevent *bufev) { diff --git a/lib/libevent/event.3 b/lib/libevent/event.3 index f4d4c926fc9..25cb2e48eff 100644 --- a/lib/libevent/event.3 +++ b/lib/libevent/event.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: event.3,v 1.19 2005/04/22 08:32:17 jmc Exp $ +.\" $OpenBSD: event.3,v 1.20 2005/05/04 03:17:48 brad Exp $ .\" .\" Copyright (c) 2000 Artur Grabowski <art@openbsd.org> .\" All rights reserved. @@ -67,7 +67,8 @@ .Nm evbuffer_drain , .Nm evbuffer_write , .Nm evbuffer_read , -.Nm evbuffer_find +.Nm evbuffer_find , +.Nm evbuffer_readline .Nd execute a function when a specific event occurs .Sh SYNOPSIS .Fd #include <sys/time.h> @@ -154,6 +155,8 @@ .Fn "evbuffer_read" "struct evbuffer *buf" "int fd" "int size" .Ft "u_char *" .Fn "evbuffer_find" "struct evbuffer *buf" "u_char *data" "size_t size" +.Ft "char *" +.Fn "evbuffer_readline" "struct evbuffer *buf" .Ft int .Fa (*event_sigcb)(void) ; .Ft volatile sig_atomic_t @@ -325,7 +328,7 @@ the call will have no effect. .Pp The function .Fn event_once -is similiar to +is similar to .Fn event_set . However, it schedules a callback to be called exactly once and does not require the caller to prepare an @@ -385,10 +388,11 @@ It is possible to disable support for .Va kqueue , poll , or .Va select -by setting the environment variable +by setting the environment variables .Va EVENT_NOKQUEUE , EVENT_NOPOLL , or -.Va EVENT_NOSELECT . +.Va EVENT_NOSELECT , +respectively. By setting the environment variable .Va EVENT_SHOW_METHOD , .Nm libevent diff --git a/lib/libevent/event.c b/lib/libevent/event.c index 0711f7d8a16..b5b9fcdcf16 100644 --- a/lib/libevent/event.c +++ b/lib/libevent/event.c @@ -1,4 +1,4 @@ -/* $OpenBSD: event.c,v 1.9 2005/04/22 00:56:25 brad Exp $ */ +/* $OpenBSD: event.c,v 1.10 2005/05/04 03:17:48 brad Exp $ */ /* * Copyright (c) 2000-2004 Niels Provos <provos@citi.umich.edu> @@ -438,6 +438,7 @@ event_once(int fd, short events, event_set(&eonce->ev, fd, events, event_once_cb, eonce); } else { /* Bad event combination */ + free(eonce); return (-1); } @@ -473,7 +474,7 @@ event_base_set(struct event_base *base, struct event *ev) return (-1); ev->ev_base = base; - ev->ev_pri = current_base->nactivequeues/2; + ev->ev_pri = base->nactivequeues/2; return (0); } diff --git a/lib/libevent/event.h b/lib/libevent/event.h index 5b2385a12c7..42292f91e46 100644 --- a/lib/libevent/event.h +++ b/lib/libevent/event.h @@ -1,4 +1,4 @@ -/* $OpenBSD: event.h,v 1.9 2005/04/22 00:56:25 brad Exp $ */ +/* $OpenBSD: event.h,v 1.10 2005/05/04 03:17:48 brad Exp $ */ /* * Copyright (c) 2000-2004 Niels Provos <provos@citi.umich.edu> @@ -40,7 +40,7 @@ extern "C" { typedef unsigned char u_char; #endif -#define LIBEVENT_VERSION "1.0c" +#define LIBEVENT_VERSION "1.0d" #define EVLIST_TIMEOUT 0x01 #define EVLIST_INSERTED 0x02 @@ -259,6 +259,7 @@ void evbuffer_free(struct evbuffer *); int evbuffer_expand(struct evbuffer *, size_t); int evbuffer_add(struct evbuffer *, void *, size_t); int evbuffer_remove(struct evbuffer *, void *, size_t); +char *evbuffer_readline(struct evbuffer *); int evbuffer_add_buffer(struct evbuffer *, struct evbuffer *); int evbuffer_add_printf(struct evbuffer *, char *fmt, ...); void evbuffer_drain(struct evbuffer *, size_t); diff --git a/lib/libevent/kqueue.c b/lib/libevent/kqueue.c index 6280399efe4..a1a02ff993b 100644 --- a/lib/libevent/kqueue.c +++ b/lib/libevent/kqueue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kqueue.c,v 1.15 2005/04/22 00:56:25 brad Exp $ */ +/* $OpenBSD: kqueue.c,v 1.16 2005/05/04 03:17:48 brad Exp $ */ /* * Copyright 2000-2002 Niels Provos <provos@citi.umich.edu> @@ -225,6 +225,7 @@ kq_dispatch(struct event_base *base, void *arg, struct timeval *tv) if (events[i].data == EBADF || events[i].data == ENOENT) continue; + errno = events[i].data; return (-1); } diff --git a/lib/libevent/log.c b/lib/libevent/log.c index 6038b389199..3d9b5000b25 100644 --- a/lib/libevent/log.c +++ b/lib/libevent/log.c @@ -1,4 +1,4 @@ -/* $OpenBSD: log.c,v 1.3 2005/04/22 00:56:25 brad Exp $ */ +/* $OpenBSD: log.c,v 1.4 2005/05/04 03:17:48 brad Exp $ */ /* * log.c @@ -87,6 +87,17 @@ event_vsnprintf(char *str, size_t size, const char *format, va_list args) return r; } +static int +event_snprintf(char *str, size_t size, const char *format, ...) +{ + va_list ap; + int r; + va_start(ap, format); + r = event_vsnprintf(str, size, format, ap); + va_end(ap); + return r; +} + void event_err(int eval, const char *fmt, ...) { @@ -163,7 +174,7 @@ _warn_helper(int severity, int log_errno, const char *fmt, va_list ap) if (log_errno >= 0) { len = strlen(buf); if (len < sizeof(buf) - 3) { - snprintf(buf + len, sizeof(buf) - len, ": %s", + event_snprintf(buf + len, sizeof(buf) - len, ": %s", strerror(log_errno)); } } diff --git a/lib/libevent/poll.c b/lib/libevent/poll.c index bc3a19006a6..64cedaef71c 100644 --- a/lib/libevent/poll.c +++ b/lib/libevent/poll.c @@ -1,4 +1,4 @@ -/* $OpenBSD: poll.c,v 1.6 2005/04/22 00:56:25 brad Exp $ */ +/* $OpenBSD: poll.c,v 1.7 2005/05/04 03:17:48 brad Exp $ */ /* * Copyright 2000-2003 Niels Provos <provos@citi.umich.edu> @@ -55,8 +55,13 @@ extern volatile sig_atomic_t evsignal_caught; struct pollop { int event_count; /* Highest number alloc */ + int fd_count; /* Size of idxplus1_by_fd */ struct pollfd *event_set; - struct event **event_back; + struct event **event_r_back; + struct event **event_w_back; + int *idxplus1_by_fd; /* Index into event_set by fd; we add 1 so + * that 0 (which is easy to memset) can mean + * "no entry." */ sigset_t evsigmask; }; @@ -108,13 +113,19 @@ poll_recalc(struct event_base *base, void *arg, int max) int poll_dispatch(struct event_base *base, void *arg, struct timeval *tv) { - int res, i, count, sec, nfds; + int res, i, count, fd_count, sec, nfds; struct event *ev; struct pollop *pop = arg; + int *idxplus1_by_fd; count = pop->event_count; + fd_count = pop->fd_count; + idxplus1_by_fd = pop->idxplus1_by_fd; + memset(idxplus1_by_fd, 0, sizeof(int)*fd_count); nfds = 0; + TAILQ_FOREACH(ev, &base->eventqueue, ev_next) { + struct pollfd *pfd = NULL; if (nfds + 1 >= count) { if (count < 32) count = 32; @@ -128,34 +139,61 @@ poll_dispatch(struct event_base *base, void *arg, struct timeval *tv) event_warn("realloc"); return (-1); } - pop->event_back = realloc(pop->event_back, + pop->event_r_back = realloc(pop->event_r_back, + count * sizeof(struct event *)); + pop->event_w_back = realloc(pop->event_w_back, count * sizeof(struct event *)); - if (pop->event_back == NULL) { + if (pop->event_r_back == NULL || + pop->event_w_back == NULL) { event_warn("realloc"); return (-1); } pop->event_count = count; } + if (!(ev->ev_events & (EV_READ|EV_WRITE))) + continue; + if (ev->ev_fd >= fd_count) { + int new_count; + if (fd_count < 32) + new_count = 32; + else + new_count = fd_count * 2; + while (new_count <= ev->ev_fd) + new_count *= 2; + idxplus1_by_fd = pop->idxplus1_by_fd = + realloc(pop->idxplus1_by_fd, new_count*sizeof(int)); + if (idxplus1_by_fd == NULL) { + event_warn("realloc"); + return (-1); + } + memset(pop->idxplus1_by_fd + fd_count, + 0, sizeof(int)*(new_count-fd_count)); + fd_count = pop->fd_count = new_count; + } + i = idxplus1_by_fd[ev->ev_fd] - 1; + if (i >= 0) { + pfd = &pop->event_set[i]; + } else { + i = nfds++; + pfd = &pop->event_set[i]; + pop->event_w_back[i] = pop->event_r_back[i] = NULL; + pfd->events = 0; + idxplus1_by_fd[ev->ev_fd] = i + 1; + } + if (ev->ev_events & EV_WRITE) { - struct pollfd *pfd = &pop->event_set[nfds]; pfd->fd = ev->ev_fd; - pfd->events = POLLOUT; + pfd->events |= POLLOUT; pfd->revents = 0; - pop->event_back[nfds] = ev; - - nfds++; + pop->event_w_back[i] = ev; } if (ev->ev_events & EV_READ) { - struct pollfd *pfd = &pop->event_set[nfds]; - pfd->fd = ev->ev_fd; - pfd->events = POLLIN; + pfd->events |= POLLIN; pfd->revents = 0; - pop->event_back[nfds] = ev; - - nfds++; + pop->event_r_back[i] = ev; } } @@ -185,8 +223,9 @@ poll_dispatch(struct event_base *base, void *arg, struct timeval *tv) return (0); for (i = 0; i < nfds; i++) { - int what = pop->event_set[i].revents; - + int what = pop->event_set[i].revents; + struct event *r_ev = NULL, *w_ev = NULL; + res = 0; /* If the file gets closed notify */ @@ -194,21 +233,27 @@ poll_dispatch(struct event_base *base, void *arg, struct timeval *tv) what |= POLLIN|POLLOUT; if (what & POLLERR) what |= POLLIN|POLLOUT; - if (what & POLLIN) + if (what & POLLIN) { res |= EV_READ; - if (what & POLLOUT) + r_ev = pop->event_r_back[i]; + } + if (what & POLLOUT) { res |= EV_WRITE; + w_ev = pop->event_w_back[i]; + } if (res == 0) continue; - ev = pop->event_back[i]; - res &= ev->ev_events; - - if (res) { - if (!(ev->ev_events & EV_PERSIST)) - event_del(ev); - event_active(ev, res, 1); - } + if (r_ev && (res & r_ev->ev_events)) { + if (!(r_ev->ev_events & EV_PERSIST)) + event_del(r_ev); + event_active(r_ev, res & r_ev->ev_events, 1); + } + if (w_ev && w_ev != r_ev && (res & w_ev->ev_events)) { + if (!(w_ev->ev_events & EV_PERSIST)) + event_del(w_ev); + event_active(w_ev, res & w_ev->ev_events, 1); + } } return (0); |