Stop passing EVTHREAD_READ and EVTHREAD_WRITE to non-rw locks.

Previously, our default lock model kind of assumed that every lock was
potentially a read-write lock.  This was a poor choice, since
read-write locks are far more expensive than regular locks, and so the
lock API should only use them when we can actually take advantage of
them.  Neither our pthreads or win32 lock implementation provided rw
locks.

Now that we have a way (not currently used!) to	indicate that we
really want a read-write lock, we shouldn't actually say "lock this
for reading" or "lock this for writing" unless we mean it.
This commit is contained in:
Nick Mathewson 2009-11-27 16:44:47 -05:00
parent 347952ffe0
commit 76cd2b70bb
15 changed files with 155 additions and 144 deletions

148
buffer.c
View File

@ -277,27 +277,27 @@ evbuffer_new(void)
void void
_evbuffer_incref(struct evbuffer *buf) _evbuffer_incref(struct evbuffer *buf)
{ {
EVBUFFER_LOCK(buf, EVTHREAD_WRITE); EVBUFFER_LOCK(buf);
++buf->refcnt; ++buf->refcnt;
EVBUFFER_UNLOCK(buf, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buf);
} }
void void
_evbuffer_incref_and_lock(struct evbuffer *buf) _evbuffer_incref_and_lock(struct evbuffer *buf)
{ {
EVBUFFER_LOCK(buf, EVTHREAD_WRITE); EVBUFFER_LOCK(buf);
++buf->refcnt; ++buf->refcnt;
} }
int int
evbuffer_defer_callbacks(struct evbuffer *buffer, struct event_base *base) evbuffer_defer_callbacks(struct evbuffer *buffer, struct event_base *base)
{ {
EVBUFFER_LOCK(buffer, EVTHREAD_WRITE); EVBUFFER_LOCK(buffer);
buffer->cb_queue = event_base_get_deferred_cb_queue(base); buffer->cb_queue = event_base_get_deferred_cb_queue(base);
buffer->deferred_cbs = 1; buffer->deferred_cbs = 1;
event_deferred_cb_init(&buffer->deferred, event_deferred_cb_init(&buffer->deferred,
evbuffer_deferred_callback, buffer); evbuffer_deferred_callback, buffer);
EVBUFFER_UNLOCK(buffer, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buffer);
return 0; return 0;
} }
@ -328,9 +328,9 @@ evbuffer_enable_locking(struct evbuffer *buf, void *lock)
void void
evbuffer_set_parent(struct evbuffer *buf, struct bufferevent *bev) evbuffer_set_parent(struct evbuffer *buf, struct bufferevent *bev)
{ {
EVBUFFER_LOCK(buf, EVTHREAD_WRITE); EVBUFFER_LOCK(buf);
buf->parent = bev; buf->parent = bev;
EVBUFFER_UNLOCK(buf, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buf);
} }
static void static void
@ -386,7 +386,7 @@ evbuffer_invoke_callbacks(struct evbuffer *buffer)
_evbuffer_incref_and_lock(buffer); _evbuffer_incref_and_lock(buffer);
if (buffer->parent) if (buffer->parent)
bufferevent_incref(buffer->parent); bufferevent_incref(buffer->parent);
EVBUFFER_UNLOCK(buffer, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buffer);
event_deferred_cb_schedule(buffer->cb_queue, &buffer->deferred); event_deferred_cb_schedule(buffer->cb_queue, &buffer->deferred);
} else { } else {
evbuffer_run_callbacks(buffer); evbuffer_run_callbacks(buffer);
@ -401,7 +401,7 @@ evbuffer_deferred_callback(struct deferred_cb *cb, void *arg)
/* XXXX It would be better to run these callbacks without holding the /* XXXX It would be better to run these callbacks without holding the
* lock */ * lock */
EVBUFFER_LOCK(buffer, EVTHREAD_WRITE); EVBUFFER_LOCK(buffer);
parent = buffer->parent; parent = buffer->parent;
evbuffer_run_callbacks(buffer); evbuffer_run_callbacks(buffer);
_evbuffer_decref_and_unlock(buffer); _evbuffer_decref_and_unlock(buffer);
@ -427,7 +427,7 @@ _evbuffer_decref_and_unlock(struct evbuffer *buffer)
ASSERT_EVBUFFER_LOCKED(buffer); ASSERT_EVBUFFER_LOCKED(buffer);
if (--buffer->refcnt > 0) { if (--buffer->refcnt > 0) {
EVBUFFER_UNLOCK(buffer, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buffer);
return; return;
} }
@ -439,7 +439,7 @@ _evbuffer_decref_and_unlock(struct evbuffer *buffer)
if (buffer->deferred_cbs) if (buffer->deferred_cbs)
event_deferred_cb_cancel(buffer->cb_queue, &buffer->deferred); event_deferred_cb_cancel(buffer->cb_queue, &buffer->deferred);
EVBUFFER_UNLOCK(buffer, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buffer);
if (buffer->own_lock) if (buffer->own_lock)
EVTHREAD_FREE_LOCK(buffer->lock, EVTHREAD_LOCKTYPE_RECURSIVE); EVTHREAD_FREE_LOCK(buffer->lock, EVTHREAD_LOCKTYPE_RECURSIVE);
mm_free(buffer); mm_free(buffer);
@ -448,20 +448,20 @@ _evbuffer_decref_and_unlock(struct evbuffer *buffer)
void void
evbuffer_free(struct evbuffer *buffer) evbuffer_free(struct evbuffer *buffer)
{ {
EVBUFFER_LOCK(buffer, EVTHREAD_WRITE); EVBUFFER_LOCK(buffer);
_evbuffer_decref_and_unlock(buffer); _evbuffer_decref_and_unlock(buffer);
} }
void void
evbuffer_lock(struct evbuffer *buf) evbuffer_lock(struct evbuffer *buf)
{ {
EVBUFFER_LOCK(buf, EVTHREAD_WRITE); EVBUFFER_LOCK(buf);
} }
void void
evbuffer_unlock(struct evbuffer *buf) evbuffer_unlock(struct evbuffer *buf)
{ {
EVBUFFER_UNLOCK(buf, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buf);
} }
size_t size_t
@ -469,11 +469,11 @@ evbuffer_get_length(const struct evbuffer *buffer)
{ {
size_t result; size_t result;
EVBUFFER_LOCK(buffer, EVTHREAD_READ); EVBUFFER_LOCK(buffer);
result = (buffer->total_len); result = (buffer->total_len);
EVBUFFER_UNLOCK(buffer, EVTHREAD_READ); EVBUFFER_UNLOCK(buffer);
return result; return result;
} }
@ -484,10 +484,10 @@ evbuffer_get_contiguous_space(const struct evbuffer *buf)
struct evbuffer_chain *chain; struct evbuffer_chain *chain;
size_t result; size_t result;
EVBUFFER_LOCK(buf, EVTHREAD_READ); EVBUFFER_LOCK(buf);
chain = buf->first; chain = buf->first;
result = (chain != NULL ? chain->off : 0); result = (chain != NULL ? chain->off : 0);
EVBUFFER_UNLOCK(buf, EVTHREAD_READ); EVBUFFER_UNLOCK(buf);
return result; return result;
} }
@ -499,7 +499,7 @@ evbuffer_reserve_space(struct evbuffer *buf, ev_ssize_t size,
struct evbuffer_chain *chain; struct evbuffer_chain *chain;
int n = -1; int n = -1;
EVBUFFER_LOCK(buf, EVTHREAD_WRITE); EVBUFFER_LOCK(buf);
if (buf->freeze_end) if (buf->freeze_end)
goto done; goto done;
if (n_vecs < 1) if (n_vecs < 1)
@ -519,7 +519,7 @@ evbuffer_reserve_space(struct evbuffer *buf, ev_ssize_t size,
} }
done: done:
EVBUFFER_UNLOCK(buf, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buf);
return n; return n;
} }
@ -534,7 +534,7 @@ evbuffer_commit_space(struct evbuffer *buf,
size_t added; size_t added;
EVBUFFER_LOCK(buf, EVTHREAD_WRITE); EVBUFFER_LOCK(buf);
if (buf->freeze_end) if (buf->freeze_end)
goto done; goto done;
if (n_vecs < 1 || n_vecs > 2) if (n_vecs < 1 || n_vecs > 2)
@ -572,7 +572,7 @@ evbuffer_commit_space(struct evbuffer *buf,
evbuffer_invoke_callbacks(buf); evbuffer_invoke_callbacks(buf);
done: done:
EVBUFFER_UNLOCK(buf, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buf);
return result; return result;
} }
@ -695,7 +695,7 @@ evbuffer_drain(struct evbuffer *buf, size_t len)
size_t old_len; size_t old_len;
int result = 0; int result = 0;
EVBUFFER_LOCK(buf, EVTHREAD_WRITE); EVBUFFER_LOCK(buf);
old_len = buf->total_len; old_len = buf->total_len;
if (old_len == 0) if (old_len == 0)
@ -743,7 +743,7 @@ evbuffer_drain(struct evbuffer *buf, size_t len)
evbuffer_invoke_callbacks(buf); evbuffer_invoke_callbacks(buf);
done: done:
EVBUFFER_UNLOCK(buf, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buf);
return result; return result;
} }
@ -758,7 +758,7 @@ evbuffer_remove(struct evbuffer *buf, void *data_out, size_t datlen)
size_t nread; size_t nread;
int result = 0; int result = 0;
EVBUFFER_LOCK(buf, EVTHREAD_WRITE); EVBUFFER_LOCK(buf);
chain = buf->first; chain = buf->first;
@ -805,7 +805,7 @@ evbuffer_remove(struct evbuffer *buf, void *data_out, size_t datlen)
result = nread; result = nread;
done: done:
EVBUFFER_UNLOCK(buf, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buf);
return result; return result;
} }
@ -899,7 +899,7 @@ evbuffer_pullup(struct evbuffer *buf, ev_ssize_t size)
unsigned char *buffer, *result = NULL; unsigned char *buffer, *result = NULL;
ev_ssize_t remaining; ev_ssize_t remaining;
EVBUFFER_LOCK(buf, EVTHREAD_WRITE); EVBUFFER_LOCK(buf);
chain = buf->first; chain = buf->first;
@ -988,7 +988,7 @@ evbuffer_pullup(struct evbuffer *buf, ev_ssize_t size)
result = (tmp->buffer + tmp->misalign); result = (tmp->buffer + tmp->misalign);
done: done:
EVBUFFER_UNLOCK(buf, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buf);
return result; return result;
} }
@ -1109,7 +1109,7 @@ evbuffer_search_eol(struct evbuffer *buffer,
size_t extra_drain = 0; size_t extra_drain = 0;
int ok = 0; int ok = 0;
EVBUFFER_LOCK(buffer, EVTHREAD_READ); EVBUFFER_LOCK(buffer);
if (start) { if (start) {
memcpy(&it, start, sizeof(it)); memcpy(&it, start, sizeof(it));
@ -1164,7 +1164,7 @@ evbuffer_search_eol(struct evbuffer *buffer,
ok = 1; ok = 1;
done: done:
EVBUFFER_UNLOCK(buffer, EVTHREAD_READ); EVBUFFER_UNLOCK(buffer);
if (!ok) { if (!ok) {
it.pos = -1; it.pos = -1;
@ -1184,7 +1184,7 @@ evbuffer_readln(struct evbuffer *buffer, size_t *n_read_out,
size_t n_to_copy=0, extra_drain=0; size_t n_to_copy=0, extra_drain=0;
char *result = NULL; char *result = NULL;
EVBUFFER_LOCK(buffer, EVTHREAD_WRITE); EVBUFFER_LOCK(buffer);
if (buffer->freeze_start) { if (buffer->freeze_start) {
goto done; goto done;
@ -1206,7 +1206,7 @@ evbuffer_readln(struct evbuffer *buffer, size_t *n_read_out,
evbuffer_drain(buffer, extra_drain); evbuffer_drain(buffer, extra_drain);
result = line; result = line;
done: done:
EVBUFFER_UNLOCK(buffer, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buffer);
if (n_read_out) if (n_read_out)
*n_read_out = result ? n_to_copy : 0; *n_read_out = result ? n_to_copy : 0;
@ -1226,7 +1226,7 @@ evbuffer_add(struct evbuffer *buf, const void *data_in, size_t datlen)
size_t remain, to_alloc; size_t remain, to_alloc;
int result = -1; int result = -1;
EVBUFFER_LOCK(buf, EVTHREAD_WRITE); EVBUFFER_LOCK(buf);
if (buf->freeze_end) { if (buf->freeze_end) {
goto done; goto done;
@ -1297,7 +1297,7 @@ out:
evbuffer_invoke_callbacks(buf); evbuffer_invoke_callbacks(buf);
result = 0; result = 0;
done: done:
EVBUFFER_UNLOCK(buf, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buf);
return result; return result;
} }
@ -1307,7 +1307,7 @@ evbuffer_prepend(struct evbuffer *buf, const void *data, size_t datlen)
struct evbuffer_chain *chain, *tmp; struct evbuffer_chain *chain, *tmp;
int result = -1; int result = -1;
EVBUFFER_LOCK(buf, EVTHREAD_WRITE); EVBUFFER_LOCK(buf);
if (buf->freeze_start) { if (buf->freeze_start) {
goto done; goto done;
@ -1364,7 +1364,7 @@ out:
evbuffer_invoke_callbacks(buf); evbuffer_invoke_callbacks(buf);
result = 0; result = 0;
done: done:
EVBUFFER_UNLOCK(buf, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buf);
return result; return result;
} }
@ -1389,7 +1389,7 @@ evbuffer_expand(struct evbuffer *buf, size_t datlen)
size_t need, length; size_t need, length;
int result = -1; int result = -1;
EVBUFFER_LOCK(buf, EVTHREAD_WRITE); EVBUFFER_LOCK(buf);
chain = buf->last; chain = buf->last;
@ -1440,7 +1440,7 @@ evbuffer_expand(struct evbuffer *buf, size_t datlen)
ok: ok:
result = 0; result = 0;
err: err:
EVBUFFER_UNLOCK(buf, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buf);
return result; return result;
} }
@ -1622,7 +1622,7 @@ evbuffer_read(struct evbuffer *buf, evutil_socket_t fd, int howmuch)
long lng = n; long lng = n;
#endif #endif
EVBUFFER_LOCK(buf, EVTHREAD_WRITE); EVBUFFER_LOCK(buf);
if (buf->freeze_end) { if (buf->freeze_end) {
result = -1; result = -1;
@ -1750,7 +1750,7 @@ evbuffer_read(struct evbuffer *buf, evutil_socket_t fd, int howmuch)
evbuffer_invoke_callbacks(buf); evbuffer_invoke_callbacks(buf);
result = n; result = n;
done: done:
EVBUFFER_UNLOCK(buf, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buf);
return result; return result;
} }
@ -1856,7 +1856,7 @@ evbuffer_write_atmost(struct evbuffer *buffer, evutil_socket_t fd,
{ {
int n = -1; int n = -1;
EVBUFFER_LOCK(buffer, EVTHREAD_WRITE); EVBUFFER_LOCK(buffer);
if (buffer->freeze_start) { if (buffer->freeze_start) {
goto done; goto done;
@ -1889,7 +1889,7 @@ evbuffer_write_atmost(struct evbuffer *buffer, evutil_socket_t fd,
evbuffer_drain(buffer, n); evbuffer_drain(buffer, n);
done: done:
EVBUFFER_UNLOCK(buffer, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buffer);
return (n); return (n);
} }
@ -1905,7 +1905,7 @@ evbuffer_find(struct evbuffer *buffer, const unsigned char *what, size_t len)
unsigned char *search; unsigned char *search;
struct evbuffer_ptr ptr; struct evbuffer_ptr ptr;
EVBUFFER_LOCK(buffer, EVTHREAD_WRITE); EVBUFFER_LOCK(buffer);
ptr = evbuffer_search(buffer, (const char *)what, len, NULL); ptr = evbuffer_search(buffer, (const char *)what, len, NULL);
if (ptr.pos < 0) { if (ptr.pos < 0) {
@ -1915,7 +1915,7 @@ evbuffer_find(struct evbuffer *buffer, const unsigned char *what, size_t len)
if (search) if (search)
search += ptr.pos; search += ptr.pos;
} }
EVBUFFER_UNLOCK(buffer,EVTHREAD_WRITE); EVBUFFER_UNLOCK(buffer);
return search; return search;
} }
@ -1926,7 +1926,7 @@ evbuffer_ptr_set(struct evbuffer *buf, struct evbuffer_ptr *pos,
size_t left = position; size_t left = position;
struct evbuffer_chain *chain = NULL; struct evbuffer_chain *chain = NULL;
EVBUFFER_LOCK(buf, EVTHREAD_READ); EVBUFFER_LOCK(buf);
switch (how) { switch (how) {
case EVBUFFER_PTR_SET: case EVBUFFER_PTR_SET:
@ -1956,7 +1956,7 @@ evbuffer_ptr_set(struct evbuffer *buf, struct evbuffer_ptr *pos,
pos->pos = -1; pos->pos = -1;
} }
EVBUFFER_UNLOCK(buf, EVTHREAD_READ); EVBUFFER_UNLOCK(buf);
return chain != NULL ? 0 : -1; return chain != NULL ? 0 : -1;
} }
@ -2013,7 +2013,7 @@ evbuffer_search_range(struct evbuffer *buffer, const char *what, size_t len, con
const unsigned char *p; const unsigned char *p;
char first; char first;
EVBUFFER_LOCK(buffer, EVTHREAD_READ); EVBUFFER_LOCK(buffer);
if (start) { if (start) {
memcpy(&pos, start, sizeof(pos)); memcpy(&pos, start, sizeof(pos));
@ -2066,7 +2066,7 @@ not_found:
pos.pos = -1; pos.pos = -1;
pos._internal.chain = NULL; pos._internal.chain = NULL;
done: done:
EVBUFFER_UNLOCK(buffer, EVTHREAD_READ); EVBUFFER_UNLOCK(buffer);
return pos; return pos;
} }
@ -2079,7 +2079,7 @@ evbuffer_peek(struct evbuffer *buffer, ev_ssize_t len,
int idx = 0; int idx = 0;
ev_ssize_t len_so_far = 0; ev_ssize_t len_so_far = 0;
EVBUFFER_LOCK(buffer, EVTHREAD_READ); EVBUFFER_LOCK(buffer);
if (start_at) { if (start_at) {
chain = start_at->_internal.chain; chain = start_at->_internal.chain;
@ -2109,7 +2109,7 @@ evbuffer_peek(struct evbuffer *buffer, ev_ssize_t len,
chain = chain->next; chain = chain->next;
} }
EVBUFFER_UNLOCK(buffer, EVTHREAD_READ); EVBUFFER_UNLOCK(buffer);
return idx; return idx;
} }
@ -2123,7 +2123,7 @@ evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap)
int sz, result = -1; int sz, result = -1;
va_list aq; va_list aq;
EVBUFFER_LOCK(buf, EVTHREAD_WRITE); EVBUFFER_LOCK(buf);
if (buf->freeze_end) { if (buf->freeze_end) {
goto done; goto done;
@ -2166,7 +2166,7 @@ evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap)
/* NOTREACHED */ /* NOTREACHED */
done: done:
EVBUFFER_UNLOCK(buf, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buf);
return result; return result;
} }
@ -2204,7 +2204,7 @@ evbuffer_add_reference(struct evbuffer *outbuf,
info->cleanupfn = cleanupfn; info->cleanupfn = cleanupfn;
info->extra = extra; info->extra = extra;
EVBUFFER_LOCK(outbuf, EVTHREAD_WRITE); EVBUFFER_LOCK(outbuf);
if (outbuf->freeze_end) { if (outbuf->freeze_end) {
/* don't call chain_free; we do not want to actually invoke /* don't call chain_free; we do not want to actually invoke
* the cleanup function */ * the cleanup function */
@ -2218,7 +2218,7 @@ evbuffer_add_reference(struct evbuffer *outbuf,
result = 0; result = 0;
done: done:
EVBUFFER_UNLOCK(outbuf, EVTHREAD_WRITE); EVBUFFER_UNLOCK(outbuf);
return result; return result;
} }
@ -2257,7 +2257,7 @@ evbuffer_add_file(struct evbuffer *outbuf, int fd,
info = EVBUFFER_CHAIN_EXTRA(struct evbuffer_chain_fd, chain); info = EVBUFFER_CHAIN_EXTRA(struct evbuffer_chain_fd, chain);
info->fd = fd; info->fd = fd;
EVBUFFER_LOCK(outbuf, EVTHREAD_WRITE); EVBUFFER_LOCK(outbuf);
if (outbuf->freeze_end) { if (outbuf->freeze_end) {
mm_free(chain); mm_free(chain);
ok = 0; ok = 0;
@ -2304,7 +2304,7 @@ evbuffer_add_file(struct evbuffer *outbuf, int fd,
info = EVBUFFER_CHAIN_EXTRA(struct evbuffer_chain_fd, chain); info = EVBUFFER_CHAIN_EXTRA(struct evbuffer_chain_fd, chain);
info->fd = fd; info->fd = fd;
EVBUFFER_LOCK(outbuf, EVTHREAD_WRITE); EVBUFFER_LOCK(outbuf);
if (outbuf->freeze_end) { if (outbuf->freeze_end) {
info->fd = -1; info->fd = -1;
evbuffer_chain_free(chain); evbuffer_chain_free(chain);
@ -2348,7 +2348,7 @@ evbuffer_add_file(struct evbuffer *outbuf, int fd,
length -= read; length -= read;
} }
EVBUFFER_LOCK(outbuf, EVTHREAD_WRITE); EVBUFFER_LOCK(outbuf);
if (outbuf->freeze_end) { if (outbuf->freeze_end) {
evbuffer_free(tmp); evbuffer_free(tmp);
ok = 0; ok = 0;
@ -2365,7 +2365,7 @@ evbuffer_add_file(struct evbuffer *outbuf, int fd,
if (ok) if (ok)
evbuffer_invoke_callbacks(outbuf); evbuffer_invoke_callbacks(outbuf);
EVBUFFER_UNLOCK(outbuf, EVTHREAD_WRITE); EVBUFFER_UNLOCK(outbuf);
return ok ? 0 : -1; return ok ? 0 : -1;
} }
@ -2374,7 +2374,7 @@ evbuffer_add_file(struct evbuffer *outbuf, int fd,
void void
evbuffer_setcb(struct evbuffer *buffer, evbuffer_cb cb, void *cbarg) evbuffer_setcb(struct evbuffer *buffer, evbuffer_cb cb, void *cbarg)
{ {
EVBUFFER_LOCK(buffer, EVTHREAD_WRITE); EVBUFFER_LOCK(buffer);
if (!TAILQ_EMPTY(&buffer->callbacks)) if (!TAILQ_EMPTY(&buffer->callbacks))
evbuffer_remove_all_callbacks(buffer); evbuffer_remove_all_callbacks(buffer);
@ -2385,7 +2385,7 @@ evbuffer_setcb(struct evbuffer *buffer, evbuffer_cb cb, void *cbarg)
ent->cb.cb_obsolete = cb; ent->cb.cb_obsolete = cb;
ent->flags |= EVBUFFER_CB_OBSOLETE; ent->flags |= EVBUFFER_CB_OBSOLETE;
} }
EVBUFFER_UNLOCK(buffer, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buffer);
} }
struct evbuffer_cb_entry * struct evbuffer_cb_entry *
@ -2394,12 +2394,12 @@ evbuffer_add_cb(struct evbuffer *buffer, evbuffer_cb_func cb, void *cbarg)
struct evbuffer_cb_entry *e; struct evbuffer_cb_entry *e;
if (! (e = mm_calloc(1, sizeof(struct evbuffer_cb_entry)))) if (! (e = mm_calloc(1, sizeof(struct evbuffer_cb_entry))))
return NULL; return NULL;
EVBUFFER_LOCK(buffer, EVTHREAD_WRITE); EVBUFFER_LOCK(buffer);
e->cb.cb_func = cb; e->cb.cb_func = cb;
e->cbarg = cbarg; e->cbarg = cbarg;
e->flags = EVBUFFER_CB_ENABLED; e->flags = EVBUFFER_CB_ENABLED;
TAILQ_INSERT_HEAD(&buffer->callbacks, e, next); TAILQ_INSERT_HEAD(&buffer->callbacks, e, next);
EVBUFFER_UNLOCK(buffer, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buffer);
return e; return e;
} }
@ -2407,9 +2407,9 @@ int
evbuffer_remove_cb_entry(struct evbuffer *buffer, evbuffer_remove_cb_entry(struct evbuffer *buffer,
struct evbuffer_cb_entry *ent) struct evbuffer_cb_entry *ent)
{ {
EVBUFFER_LOCK(buffer, EVTHREAD_WRITE); EVBUFFER_LOCK(buffer);
TAILQ_REMOVE(&buffer->callbacks, ent, next); TAILQ_REMOVE(&buffer->callbacks, ent, next);
EVBUFFER_UNLOCK(buffer, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buffer);
mm_free(ent); mm_free(ent);
return 0; return 0;
} }
@ -2419,7 +2419,7 @@ evbuffer_remove_cb(struct evbuffer *buffer, evbuffer_cb_func cb, void *cbarg)
{ {
struct evbuffer_cb_entry *cbent; struct evbuffer_cb_entry *cbent;
int result = -1; int result = -1;
EVBUFFER_LOCK(buffer, EVTHREAD_WRITE); EVBUFFER_LOCK(buffer);
TAILQ_FOREACH(cbent, &buffer->callbacks, next) { TAILQ_FOREACH(cbent, &buffer->callbacks, next) {
if (cb == cbent->cb.cb_func && cbarg == cbent->cbarg) { if (cb == cbent->cb.cb_func && cbarg == cbent->cbarg) {
result = evbuffer_remove_cb_entry(buffer, cbent); result = evbuffer_remove_cb_entry(buffer, cbent);
@ -2427,7 +2427,7 @@ evbuffer_remove_cb(struct evbuffer *buffer, evbuffer_cb_func cb, void *cbarg)
} }
} }
done: done:
EVBUFFER_UNLOCK(buffer, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buffer);
return result; return result;
} }
@ -2437,9 +2437,9 @@ evbuffer_cb_set_flags(struct evbuffer *buffer,
{ {
/* the user isn't allowed to mess with these. */ /* the user isn't allowed to mess with these. */
flags &= ~EVBUFFER_CB_INTERNAL_FLAGS; flags &= ~EVBUFFER_CB_INTERNAL_FLAGS;
EVBUFFER_LOCK(buffer, EVTHREAD_WRITE); EVBUFFER_LOCK(buffer);
cb->flags |= flags; cb->flags |= flags;
EVBUFFER_UNLOCK(buffer, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buffer);
return 0; return 0;
} }
@ -2449,33 +2449,33 @@ evbuffer_cb_clear_flags(struct evbuffer *buffer,
{ {
/* the user isn't allowed to mess with these. */ /* the user isn't allowed to mess with these. */
flags &= ~EVBUFFER_CB_INTERNAL_FLAGS; flags &= ~EVBUFFER_CB_INTERNAL_FLAGS;
EVBUFFER_LOCK(buffer, EVTHREAD_WRITE); EVBUFFER_LOCK(buffer);
cb->flags &= ~flags; cb->flags &= ~flags;
EVBUFFER_UNLOCK(buffer, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buffer);
return 0; return 0;
} }
int int
evbuffer_freeze(struct evbuffer *buffer, int start) evbuffer_freeze(struct evbuffer *buffer, int start)
{ {
EVBUFFER_LOCK(buffer, EVTHREAD_WRITE); EVBUFFER_LOCK(buffer);
if (start) if (start)
buffer->freeze_start = 1; buffer->freeze_start = 1;
else else
buffer->freeze_end = 1; buffer->freeze_end = 1;
EVBUFFER_UNLOCK(buffer, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buffer);
return 0; return 0;
} }
int int
evbuffer_unfreeze(struct evbuffer *buffer, int start) evbuffer_unfreeze(struct evbuffer *buffer, int start)
{ {
EVBUFFER_LOCK(buffer, EVTHREAD_WRITE); EVBUFFER_LOCK(buffer);
if (start) if (start)
buffer->freeze_start = 0; buffer->freeze_start = 0;
else else
buffer->freeze_end = 0; buffer->freeze_end = 0;
EVBUFFER_UNLOCK(buffer, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buffer);
return 0; return 0;
} }

View File

@ -98,7 +98,7 @@ evbuffer_commit_read(struct evbuffer *evbuf, ev_ssize_t nBytes)
struct evbuffer_iovec iov[2]; struct evbuffer_iovec iov[2];
int n_vec; int n_vec;
EVBUFFER_LOCK(evbuf, EVTHREAD_WRITE); EVBUFFER_LOCK(evbuf);
EVUTIL_ASSERT(buf->read_in_progress && !buf->write_in_progress); EVUTIL_ASSERT(buf->read_in_progress && !buf->write_in_progress);
EVUTIL_ASSERT(nBytes >= 0); // XXXX Can this be false? EVUTIL_ASSERT(nBytes >= 0); // XXXX Can this be false?
@ -130,7 +130,7 @@ evbuffer_commit_write(struct evbuffer *evbuf, ev_ssize_t nBytes)
{ {
struct evbuffer_overlapped *buf = upcast_evbuffer(evbuf); struct evbuffer_overlapped *buf = upcast_evbuffer(evbuf);
EVBUFFER_LOCK(evbuf, EVTHREAD_WRITE); EVBUFFER_LOCK(evbuf);
EVUTIL_ASSERT(buf->write_in_progress && !buf->read_in_progress); EVUTIL_ASSERT(buf->write_in_progress && !buf->read_in_progress);
evbuffer_unfreeze(evbuf, 1); evbuffer_unfreeze(evbuf, 1);
evbuffer_drain(evbuf, nBytes); evbuffer_drain(evbuf, nBytes);
@ -170,7 +170,7 @@ evbuffer_launch_write(struct evbuffer *buf, ev_ssize_t at_most,
return -1; return -1;
} }
EVBUFFER_LOCK(buf, EVTHREAD_WRITE); EVBUFFER_LOCK(buf);
EVUTIL_ASSERT(!buf_o->read_in_progress); EVUTIL_ASSERT(!buf_o->read_in_progress);
if (buf->freeze_start || buf_o->write_in_progress) if (buf->freeze_start || buf_o->write_in_progress)
goto done; goto done;
@ -221,7 +221,7 @@ evbuffer_launch_write(struct evbuffer *buf, ev_ssize_t at_most,
buf_o->write_in_progress = 1; buf_o->write_in_progress = 1;
r = 0; r = 0;
done: done:
EVBUFFER_UNLOCK(buf, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buf);
return r; return r;
} }
@ -240,7 +240,7 @@ evbuffer_launch_read(struct evbuffer *buf, size_t at_most,
if (!buf_o) if (!buf_o)
return -1; return -1;
EVBUFFER_LOCK(buf, EVTHREAD_WRITE); EVBUFFER_LOCK(buf);
EVUTIL_ASSERT(!buf_o->write_in_progress); EVUTIL_ASSERT(!buf_o->write_in_progress);
if (buf->freeze_end || buf_o->read_in_progress) if (buf->freeze_end || buf_o->read_in_progress)
goto done; goto done;
@ -286,7 +286,7 @@ evbuffer_launch_read(struct evbuffer *buf, size_t at_most,
buf_o->read_in_progress = 1; buf_o->read_in_progress = 1;
r = 0; r = 0;
done: done:
EVBUFFER_UNLOCK(buf, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buf);
return r; return r;
} }
@ -301,9 +301,9 @@ void
_evbuffer_overlapped_set_fd(struct evbuffer *buf, evutil_socket_t fd) _evbuffer_overlapped_set_fd(struct evbuffer *buf, evutil_socket_t fd)
{ {
struct evbuffer_overlapped *buf_o = upcast_evbuffer(buf); struct evbuffer_overlapped *buf_o = upcast_evbuffer(buf);
EVBUFFER_LOCK(buf, EVTHREAD_WRITE); EVBUFFER_LOCK(buf);
/* XXX is this right?, should it cancel current I/O operations? */ /* XXX is this right?, should it cancel current I/O operations? */
if (buf_o) if (buf_o)
buf_o->fd = fd; buf_o->fd = fd;
EVBUFFER_UNLOCK(buf, EVTHREAD_WRITE); EVBUFFER_UNLOCK(buf);
} }

View File

@ -228,14 +228,14 @@ void _bufferevent_generic_adj_timeouts(struct bufferevent *bev);
#define BEV_LOCK(b) do { \ #define BEV_LOCK(b) do { \
struct bufferevent_private *locking = BEV_UPCAST(b); \ struct bufferevent_private *locking = BEV_UPCAST(b); \
if (locking->lock) \ if (locking->lock) \
EVLOCK_LOCK(locking->lock, EVTHREAD_WRITE); \ EVLOCK_LOCK(locking->lock, 0); \
} while(0) } while(0)
/** Internal: Release the lock (if any) on a bufferevent */ /** Internal: Release the lock (if any) on a bufferevent */
#define BEV_UNLOCK(b) do { \ #define BEV_UNLOCK(b) do { \
struct bufferevent_private *locking = BEV_UPCAST(b); \ struct bufferevent_private *locking = BEV_UPCAST(b); \
if (locking->lock) \ if (locking->lock) \
EVLOCK_UNLOCK(locking->lock, EVTHREAD_WRITE); \ EVLOCK_UNLOCK(locking->lock, 0); \
} while(0) } while(0)
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -176,11 +176,11 @@ devpoll_dispatch(struct event_base *base, struct timeval *tv)
dvp.dp_nfds = devpollop->nevents; dvp.dp_nfds = devpollop->nevents;
dvp.dp_timeout = timeout; dvp.dp_timeout = timeout;
EVBASE_RELEASE_LOCK(base, EVTHREAD_WRITE, th_base_lock); EVBASE_RELEASE_LOCK(base, th_base_lock);
res = ioctl(devpollop->dpfd, DP_POLL, &dvp); res = ioctl(devpollop->dpfd, DP_POLL, &dvp);
EVBASE_ACQUIRE_LOCK(base, EVTHREAD_WRITE, th_base_lock); EVBASE_ACQUIRE_LOCK(base, th_base_lock);
if (res == -1) { if (res == -1) {
if (errno != EINTR) { if (errno != EINTR) {

View File

@ -145,11 +145,11 @@ epoll_dispatch(struct event_base *base, struct timeval *tv)
timeout = MAX_EPOLL_TIMEOUT_MSEC; timeout = MAX_EPOLL_TIMEOUT_MSEC;
} }
EVBASE_RELEASE_LOCK(base, EVTHREAD_WRITE, th_base_lock); EVBASE_RELEASE_LOCK(base, th_base_lock);
res = epoll_wait(epollop->epfd, events, epollop->nevents, timeout); res = epoll_wait(epollop->epfd, events, epollop->nevents, timeout);
EVBASE_ACQUIRE_LOCK(base, EVTHREAD_WRITE, th_base_lock); EVBASE_ACQUIRE_LOCK(base, th_base_lock);
if (res == -1) { if (res == -1) {
if (errno != EINTR) { if (errno != EINTR) {

View File

@ -222,21 +222,20 @@ struct evbuffer_chain_reference {
((struct evbuffer*)(buffer))->lock_count--; \ ((struct evbuffer*)(buffer))->lock_count--; \
} while (0) } while (0)
#define EVBUFFER_LOCK(buffer, mode) \ #define EVBUFFER_LOCK(buffer) \
do { \ do { \
EVLOCK_LOCK((buffer)->lock, (mode)); \ EVLOCK_LOCK((buffer)->lock, 0); \
_EVBUFFER_INCREMENT_LOCK_COUNT(buffer); \ _EVBUFFER_INCREMENT_LOCK_COUNT(buffer); \
} while(0) } while(0)
#define EVBUFFER_UNLOCK(buffer, mode) \ #define EVBUFFER_UNLOCK(buffer) \
do { \ do { \
_EVBUFFER_DECREMENT_LOCK_COUNT(buffer); \ _EVBUFFER_DECREMENT_LOCK_COUNT(buffer); \
EVLOCK_UNLOCK((buffer)->lock, (mode)); \ EVLOCK_UNLOCK((buffer)->lock, 0); \
} while(0) } while(0)
#define EVBUFFER_LOCK2(buffer1, buffer2) \ #define EVBUFFER_LOCK2(buffer1, buffer2) \
do { \ do { \
EVLOCK_LOCK2((buffer1)->lock, (buffer2)->lock, \ EVLOCK_LOCK2((buffer1)->lock, (buffer2)->lock, 0, 0); \
EVTHREAD_WRITE, EVTHREAD_WRITE); \
_EVBUFFER_INCREMENT_LOCK_COUNT(buffer1); \ _EVBUFFER_INCREMENT_LOCK_COUNT(buffer1); \
_EVBUFFER_INCREMENT_LOCK_COUNT(buffer2); \ _EVBUFFER_INCREMENT_LOCK_COUNT(buffer2); \
} while(0) } while(0)
@ -244,8 +243,7 @@ struct evbuffer_chain_reference {
do { \ do { \
_EVBUFFER_DECREMENT_LOCK_COUNT(buffer1); \ _EVBUFFER_DECREMENT_LOCK_COUNT(buffer1); \
_EVBUFFER_DECREMENT_LOCK_COUNT(buffer2); \ _EVBUFFER_DECREMENT_LOCK_COUNT(buffer2); \
EVLOCK_UNLOCK2((buffer1)->lock, (buffer2)->lock, \ EVLOCK_UNLOCK2((buffer1)->lock, (buffer2)->lock, 0, 0); \
EVTHREAD_WRITE, EVTHREAD_WRITE); \
} while(0) } while(0)
/** Increase the reference count of buf by one. */ /** Increase the reference count of buf by one. */

View File

@ -421,7 +421,7 @@ static int strtoint(const char *const str);
#define EVDNS_LOCK(base) \ #define EVDNS_LOCK(base) \
do { \ do { \
if ((base)->lock) { \ if ((base)->lock) { \
EVLOCK_LOCK((base)->lock, EVTHREAD_WRITE); \ EVLOCK_LOCK((base)->lock, 0); \
} \ } \
++(base)->lock_count; \ ++(base)->lock_count; \
} while (0) } while (0)
@ -430,7 +430,7 @@ static int strtoint(const char *const str);
EVUTIL_ASSERT((base)->lock_count > 0); \ EVUTIL_ASSERT((base)->lock_count > 0); \
--(base)->lock_count; \ --(base)->lock_count; \
if ((base)->lock) { \ if ((base)->lock) { \
EVLOCK_UNLOCK((base)->lock, EVTHREAD_WRITE); \ EVLOCK_UNLOCK((base)->lock, 0); \
} \ } \
} while (0) } while (0)
#define ASSERT_LOCKED(base) EVUTIL_ASSERT((base)->lock_count > 0) #define ASSERT_LOCKED(base) EVUTIL_ASSERT((base)->lock_count > 0)

49
event.c
View File

@ -760,7 +760,7 @@ common_timeout_callback(evutil_socket_t fd, short what, void *arg)
struct common_timeout_list *ctl = arg; struct common_timeout_list *ctl = arg;
struct event_base *base = ctl->base; struct event_base *base = ctl->base;
struct event *ev = NULL; struct event *ev = NULL;
EVBASE_ACQUIRE_LOCK(base, EVTHREAD_WRITE, th_base_lock); EVBASE_ACQUIRE_LOCK(base, th_base_lock);
gettime(base, &now); gettime(base, &now);
while (1) { while (1) {
ev = TAILQ_FIRST(&ctl->events); ev = TAILQ_FIRST(&ctl->events);
@ -773,7 +773,7 @@ common_timeout_callback(evutil_socket_t fd, short what, void *arg)
} }
if (ev) if (ev)
common_timeout_schedule(ctl, &now, ev); common_timeout_schedule(ctl, &now, ev);
EVBASE_RELEASE_LOCK(base, EVTHREAD_WRITE, th_base_lock); EVBASE_RELEASE_LOCK(base, th_base_lock);
} }
#define MAX_COMMON_TIMEOUTS 256 #define MAX_COMMON_TIMEOUTS 256
@ -787,7 +787,7 @@ event_base_init_common_timeout(struct event_base *base,
const struct timeval *result=NULL; const struct timeval *result=NULL;
struct common_timeout_list *new_ctl; struct common_timeout_list *new_ctl;
EVBASE_ACQUIRE_LOCK(base, EVTHREAD_WRITE, th_base_lock); EVBASE_ACQUIRE_LOCK(base, th_base_lock);
if (duration->tv_usec > 1000000) { if (duration->tv_usec > 1000000) {
memcpy(&tv, duration, sizeof(struct timeval)); memcpy(&tv, duration, sizeof(struct timeval));
if (is_common_timeout(duration, base)) if (is_common_timeout(duration, base))
@ -848,7 +848,7 @@ done:
if (result) if (result)
EVUTIL_ASSERT(is_common_timeout(result, base)); EVUTIL_ASSERT(is_common_timeout(result, base));
EVBASE_RELEASE_LOCK(base, EVTHREAD_WRITE, th_base_lock); EVBASE_RELEASE_LOCK(base, th_base_lock);
return result; return result;
} }
@ -915,10 +915,9 @@ event_process_active_single_queue(struct event_base *base,
base->current_event = ev; base->current_event = ev;
EVBASE_ACQUIRE_LOCK(base, EVTHREAD_WRITE, current_event_lock); EVBASE_ACQUIRE_LOCK(base, current_event_lock);
EVBASE_RELEASE_LOCK(base, EVBASE_RELEASE_LOCK(base, th_base_lock);
EVTHREAD_WRITE, th_base_lock);
switch (ev->ev_closure) { switch (ev->ev_closure) {
case EV_CLOSURE_SIGNAL: case EV_CLOSURE_SIGNAL:
@ -934,8 +933,8 @@ event_process_active_single_queue(struct event_base *base,
break; break;
} }
EVBASE_RELEASE_LOCK(base, EVTHREAD_WRITE, current_event_lock); EVBASE_RELEASE_LOCK(base, current_event_lock);
EVBASE_ACQUIRE_LOCK(base, EVTHREAD_WRITE, th_base_lock); EVBASE_ACQUIRE_LOCK(base, th_base_lock);
base->current_event = NULL; base->current_event = NULL;
if (base->event_break) if (base->event_break)
@ -1053,9 +1052,9 @@ event_base_loopbreak(struct event_base *event_base)
if (event_base == NULL) if (event_base == NULL)
return (-1); return (-1);
EVBASE_ACQUIRE_LOCK(event_base, EVTHREAD_WRITE, th_base_lock); EVBASE_ACQUIRE_LOCK(event_base, th_base_lock);
event_base->event_break = 1; event_base->event_break = 1;
EVBASE_RELEASE_LOCK(event_base, EVTHREAD_WRITE, th_base_lock); EVBASE_RELEASE_LOCK(event_base, th_base_lock);
if (!EVBASE_IN_THREAD(event_base)) { if (!EVBASE_IN_THREAD(event_base)) {
return evthread_notify_base(event_base); return evthread_notify_base(event_base);
@ -1068,9 +1067,9 @@ int
event_base_got_break(struct event_base *event_base) event_base_got_break(struct event_base *event_base)
{ {
int res; int res;
EVBASE_ACQUIRE_LOCK(event_base, EVTHREAD_READ, th_base_lock); EVBASE_ACQUIRE_LOCK(event_base, th_base_lock);
res = event_base->event_break; res = event_base->event_break;
EVBASE_RELEASE_LOCK(event_base, EVTHREAD_READ, th_base_lock); EVBASE_RELEASE_LOCK(event_base, th_base_lock);
return res; return res;
} }
@ -1078,9 +1077,9 @@ int
event_base_got_exit(struct event_base *event_base) event_base_got_exit(struct event_base *event_base)
{ {
int res; int res;
EVBASE_ACQUIRE_LOCK(event_base, EVTHREAD_READ, th_base_lock); EVBASE_ACQUIRE_LOCK(event_base, th_base_lock);
res = event_base->event_gotterm; res = event_base->event_gotterm;
EVBASE_RELEASE_LOCK(event_base, EVTHREAD_READ, th_base_lock); EVBASE_RELEASE_LOCK(event_base, th_base_lock);
return res; return res;
} }
@ -1102,7 +1101,7 @@ event_base_loop(struct event_base *base, int flags)
/* Grab the lock. We will release it inside evsel.dispatch, and again /* Grab the lock. We will release it inside evsel.dispatch, and again
* as we invoke user callbacks. */ * as we invoke user callbacks. */
EVBASE_ACQUIRE_LOCK(base, EVTHREAD_WRITE, th_base_lock); EVBASE_ACQUIRE_LOCK(base, th_base_lock);
clear_time_cache(base); clear_time_cache(base);
@ -1169,7 +1168,7 @@ event_base_loop(struct event_base *base, int flags)
clear_time_cache(base); clear_time_cache(base);
EVBASE_RELEASE_LOCK(base, EVTHREAD_WRITE, th_base_lock); EVBASE_RELEASE_LOCK(base, th_base_lock);
event_debug(("%s: asked to terminate loop.", __func__)); event_debug(("%s: asked to terminate loop.", __func__));
return (0); return (0);
@ -1419,11 +1418,11 @@ event_add(struct event *ev, const struct timeval *tv)
{ {
int res; int res;
EVBASE_ACQUIRE_LOCK(ev->ev_base, EVTHREAD_WRITE, th_base_lock); EVBASE_ACQUIRE_LOCK(ev->ev_base, th_base_lock);
res = event_add_internal(ev, tv, 0); res = event_add_internal(ev, tv, 0);
EVBASE_RELEASE_LOCK(ev->ev_base, EVTHREAD_WRITE, th_base_lock); EVBASE_RELEASE_LOCK(ev->ev_base, th_base_lock);
return (res); return (res);
} }
@ -1602,11 +1601,11 @@ event_del(struct event *ev)
{ {
int res; int res;
EVBASE_ACQUIRE_LOCK(ev->ev_base, EVTHREAD_WRITE, th_base_lock); EVBASE_ACQUIRE_LOCK(ev->ev_base, th_base_lock);
res = event_del_internal(ev); res = event_del_internal(ev);
EVBASE_RELEASE_LOCK(ev->ev_base, EVTHREAD_WRITE, th_base_lock); EVBASE_RELEASE_LOCK(ev->ev_base, th_base_lock);
return (res); return (res);
} }
@ -1634,7 +1633,7 @@ event_del_internal(struct event *ev)
base = ev->ev_base; base = ev->ev_base;
need_cur_lock = (base->current_event == ev); need_cur_lock = (base->current_event == ev);
if (need_cur_lock) if (need_cur_lock)
EVBASE_ACQUIRE_LOCK(base, EVTHREAD_WRITE, current_event_lock); EVBASE_ACQUIRE_LOCK(base, current_event_lock);
EVUTIL_ASSERT(!(ev->ev_flags & ~EVLIST_ALL)); EVUTIL_ASSERT(!(ev->ev_flags & ~EVLIST_ALL));
@ -1678,7 +1677,7 @@ event_del_internal(struct event *ev)
evthread_notify_base(base); evthread_notify_base(base);
if (need_cur_lock) if (need_cur_lock)
EVBASE_RELEASE_LOCK(base, EVTHREAD_WRITE, current_event_lock); EVBASE_RELEASE_LOCK(base, current_event_lock);
return (res); return (res);
} }
@ -1686,11 +1685,11 @@ event_del_internal(struct event *ev)
void void
event_active(struct event *ev, int res, short ncalls) event_active(struct event *ev, int res, short ncalls)
{ {
EVBASE_ACQUIRE_LOCK(ev->ev_base, EVTHREAD_WRITE, th_base_lock); EVBASE_ACQUIRE_LOCK(ev->ev_base, th_base_lock);
event_active_nolock(ev, res, ncalls); event_active_nolock(ev, res, ncalls);
EVBASE_RELEASE_LOCK(ev->ev_base, EVTHREAD_WRITE, th_base_lock); EVBASE_RELEASE_LOCK(ev->ev_base, th_base_lock);
} }

View File

@ -297,12 +297,12 @@ evport_dispatch(struct event_base *base, struct timeval *tv)
} }
} }
EVBASE_RELEASE_LOCK(base, EVTHREAD_WRITE, th_base_lock); EVBASE_RELEASE_LOCK(base, th_base_lock);
res = port_getn(epdp->ed_port, pevtlist, EVENTS_PER_GETN, res = port_getn(epdp->ed_port, pevtlist, EVENTS_PER_GETN,
(unsigned int *) &nevents, ts_p); (unsigned int *) &nevents, ts_p);
EVBASE_ACQUIRE_LOCK(base, EVTHREAD_WRITE, th_base_lock); EVBASE_ACQUIRE_LOCK(base, th_base_lock);
if (res == -1) { if (res == -1) {
if (errno == EINTR || errno == EAGAIN) { if (errno == EINTR || errno == EAGAIN) {

View File

@ -118,16 +118,16 @@ extern unsigned long (*_evthread_id_fn)(void);
/** Lock an event_base, if it is set up for locking. Acquires the lock /** Lock an event_base, if it is set up for locking. Acquires the lock
in the base structure whose field is named 'lck'. */ in the base structure whose field is named 'lockvar'. */
#define EVBASE_ACQUIRE_LOCK(base, mode, lockvar) do { \ #define EVBASE_ACQUIRE_LOCK(base, lockvar) do { \
if (EVBASE_USING_LOCKS(base)) \ if (EVBASE_USING_LOCKS(base)) \
_evthread_lock_fns.lock(mode, (base)->lockvar); \ _evthread_lock_fns.lock(0, (base)->lockvar); \
} while (0) } while (0)
/** Unlock an event_base, if it is set up for locking. */ /** Unlock an event_base, if it is set up for locking. */
#define EVBASE_RELEASE_LOCK(base, mode, lockvar) do { \ #define EVBASE_RELEASE_LOCK(base, lockvar) do { \
if (EVBASE_USING_LOCKS(base)) \ if (EVBASE_USING_LOCKS(base)) \
_evthread_lock_fns.unlock(mode, (base)->lockvar); \ _evthread_lock_fns.unlock(0, (base)->lockvar); \
} while (0) } while (0)
#else /* _EVENT_DISABLE_THREAD_SUPPORT */ #else /* _EVENT_DISABLE_THREAD_SUPPORT */
@ -141,8 +141,8 @@ extern unsigned long (*_evthread_id_fn)(void);
#define EVLOCK_UNLOCK2(lock1,lock2,mode1,mode2) _EVUTIL_NIL_STMT #define EVLOCK_UNLOCK2(lock1,lock2,mode1,mode2) _EVUTIL_NIL_STMT
#define EVBASE_IN_THREAD(base) 1 #define EVBASE_IN_THREAD(base) 1
#define EVBASE_ACQUIRE_LOCK(base, mode, lock) _EVUTIL_NIL_STMT #define EVBASE_ACQUIRE_LOCK(base, lock) _EVUTIL_NIL_STMT
#define EVBASE_RELEASE_LOCK(base, mode, lock) _EVUTIL_NIL_STMT #define EVBASE_RELEASE_LOCK(base, lock) _EVUTIL_NIL_STMT
#endif #endif

View File

@ -38,7 +38,7 @@
#include "util-internal.h" #include "util-internal.h"
/* globals */ /* globals */
static int lock_debugging_enabled = 0; int _evthread_lock_debugging_enabled = 0;
struct evthread_lock_callbacks _evthread_lock_fns = { struct evthread_lock_callbacks _evthread_lock_fns = {
0, 0, NULL, NULL, NULL, NULL 0, 0, NULL, NULL, NULL, NULL
}; };
@ -58,7 +58,8 @@ int
evthread_set_lock_callbacks(const struct evthread_lock_callbacks *cbs) evthread_set_lock_callbacks(const struct evthread_lock_callbacks *cbs)
{ {
struct evthread_lock_callbacks *target = struct evthread_lock_callbacks *target =
lock_debugging_enabled ? &_original_lock_fns : &_evthread_lock_fns; _evthread_lock_debugging_enabled
? &_original_lock_fns : &_evthread_lock_fns;
if (!cbs) { if (!cbs) {
memset(target, 0, sizeof(_evthread_lock_fns)); memset(target, 0, sizeof(_evthread_lock_fns));
@ -149,6 +150,8 @@ evthread_set_lock_create_callbacks(void *(*alloc_fn)(void),
struct debug_lock { struct debug_lock {
unsigned locktype; unsigned locktype;
/* XXXX if we ever use read-write locks, we will need a separate
* lock to protect count. */
int count; int count;
void *lock; void *lock;
}; };
@ -176,6 +179,7 @@ debug_lock_free(void *lock_, unsigned locktype)
{ {
struct debug_lock *lock = lock_; struct debug_lock *lock = lock_;
EVUTIL_ASSERT(lock->count == 0); EVUTIL_ASSERT(lock->count == 0);
EVUTIL_ASSERT(locktype == lock->locktype);
if (_original_lock_fns.free) { if (_original_lock_fns.free) {
_original_lock_fns.free(lock->lock, _original_lock_fns.free(lock->lock,
lock->locktype|EVTHREAD_LOCKTYPE_RECURSIVE); lock->locktype|EVTHREAD_LOCKTYPE_RECURSIVE);
@ -190,6 +194,10 @@ debug_lock_lock(unsigned mode, void *lock_)
{ {
struct debug_lock *lock = lock_; struct debug_lock *lock = lock_;
int res = 0; int res = 0;
if (lock->locktype & EVTHREAD_LOCKTYPE_READWRITE)
EVUTIL_ASSERT(mode & (EVTHREAD_READ|EVTHREAD_WRITE));
else
EVUTIL_ASSERT((mode & (EVTHREAD_READ|EVTHREAD_WRITE)) == 0);
if (_original_lock_fns.lock) if (_original_lock_fns.lock)
res = _original_lock_fns.lock(mode, lock->lock); res = _original_lock_fns.lock(mode, lock->lock);
if (!res) { if (!res) {
@ -205,6 +213,10 @@ debug_lock_unlock(unsigned mode, void *lock_)
{ {
struct debug_lock *lock = lock_; struct debug_lock *lock = lock_;
int res = 0; int res = 0;
if (lock->locktype & EVTHREAD_LOCKTYPE_READWRITE)
EVUTIL_ASSERT(mode & (EVTHREAD_READ|EVTHREAD_WRITE));
else
EVUTIL_ASSERT((mode & (EVTHREAD_READ|EVTHREAD_WRITE)) == 0);
--lock->count; --lock->count;
EVUTIL_ASSERT(lock->count >= 0); EVUTIL_ASSERT(lock->count >= 0);
if (_original_lock_fns.unlock) if (_original_lock_fns.unlock)
@ -223,11 +235,13 @@ evthread_enable_lock_debuging(void)
debug_lock_lock, debug_lock_lock,
debug_lock_unlock debug_lock_unlock
}; };
if (_evthread_lock_debugging_enabled)
return;
memcpy(&_original_lock_fns, &_evthread_lock_fns, memcpy(&_original_lock_fns, &_evthread_lock_fns,
sizeof(struct evthread_lock_callbacks)); sizeof(struct evthread_lock_callbacks));
memcpy(&_evthread_lock_fns, &cbs, memcpy(&_evthread_lock_fns, &cbs,
sizeof(struct evthread_lock_callbacks)); sizeof(struct evthread_lock_callbacks));
lock_debugging_enabled = 1; _evthread_lock_debugging_enabled = 1;
} }
#endif #endif

View File

@ -238,12 +238,12 @@ kq_dispatch(struct event_base *base, struct timeval *tv)
SWAP(int, kqop->nchanges, kqop->n_pend_changes); SWAP(int, kqop->nchanges, kqop->n_pend_changes);
SWAP(int, kqop->changes_size, kqop->pend_changes_size); SWAP(int, kqop->changes_size, kqop->pend_changes_size);
EVBASE_RELEASE_LOCK(base, EVTHREAD_WRITE, th_base_lock); EVBASE_RELEASE_LOCK(base, th_base_lock);
res = kevent(kqop->kq, kqop->pend_changes, kqop->n_pend_changes, res = kevent(kqop->kq, kqop->pend_changes, kqop->n_pend_changes,
events, kqop->events_size, ts_p); events, kqop->events_size, ts_p);
EVBASE_ACQUIRE_LOCK(base, EVTHREAD_WRITE, th_base_lock); EVBASE_ACQUIRE_LOCK(base, th_base_lock);
kqop->n_pend_changes = 0; kqop->n_pend_changes = 0;
if (res == -1) { if (res == -1) {

4
poll.c
View File

@ -155,11 +155,11 @@ poll_dispatch(struct event_base *base, struct timeval *tv)
if (tv != NULL) if (tv != NULL)
msec = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000; msec = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
EVBASE_RELEASE_LOCK(base, EVTHREAD_WRITE, th_base_lock); EVBASE_RELEASE_LOCK(base, th_base_lock);
res = poll(event_set, nfds, msec); res = poll(event_set, nfds, msec);
EVBASE_ACQUIRE_LOCK(base, EVTHREAD_WRITE, th_base_lock); EVBASE_ACQUIRE_LOCK(base, th_base_lock);
if (res == -1) { if (res == -1) {
if (errno != EINTR) { if (errno != EINTR) {

View File

@ -144,12 +144,12 @@ select_dispatch(struct event_base *base, struct timeval *tv)
nfds = sop->event_fds+1; nfds = sop->event_fds+1;
EVBASE_RELEASE_LOCK(base, EVTHREAD_WRITE, th_base_lock); EVBASE_RELEASE_LOCK(base, th_base_lock);
res = select(nfds, sop->event_readset_out, res = select(nfds, sop->event_readset_out,
sop->event_writeset_out, NULL, tv); sop->event_writeset_out, NULL, tv);
EVBASE_ACQUIRE_LOCK(base, EVTHREAD_WRITE, th_base_lock); EVBASE_ACQUIRE_LOCK(base, th_base_lock);
check_selectop(sop); check_selectop(sop);

View File

@ -309,14 +309,14 @@ win32_dispatch(struct event_base *base, struct timeval *tv)
return (0); return (0);
} }
EVBASE_RELEASE_LOCK(base, EVTHREAD_WRITE, th_base_lock); EVBASE_RELEASE_LOCK(base, th_base_lock);
res = select(fd_count, res = select(fd_count,
(struct fd_set*)win32op->readset_out, (struct fd_set*)win32op->readset_out,
(struct fd_set*)win32op->writeset_out, (struct fd_set*)win32op->writeset_out,
(struct fd_set*)win32op->exset_out, tv); (struct fd_set*)win32op->exset_out, tv);
EVBASE_ACQUIRE_LOCK(base, EVTHREAD_WRITE, th_base_lock); EVBASE_ACQUIRE_LOCK(base, th_base_lock);
event_debug(("%s: select returned %d", __func__, res)); event_debug(("%s: select returned %d", __func__, res));