summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libevent/buffer.c51
-rw-r--r--lib/libevent/evbuffer.c9
-rw-r--r--lib/libevent/event.314
-rw-r--r--lib/libevent/event.c5
-rw-r--r--lib/libevent/event.h5
-rw-r--r--lib/libevent/kqueue.c3
-rw-r--r--lib/libevent/log.c15
-rw-r--r--lib/libevent/poll.c101
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);