Add the abilitity to mark some buffer callbacks as never-deferred.

This commit is contained in:
Nick Mathewson 2009-11-23 15:53:24 -05:00
parent 689fc091a5
commit 438f9ed26c
3 changed files with 30 additions and 25 deletions

View File

@ -123,13 +123,6 @@ static int use_mmap = 1;
/* Mask of all internal-use-only flags. */
#define EVBUFFER_CB_INTERNAL_FLAGS 0xffff0000
#if 0
/* Flag set on suspended callbacks. */
#define EVBUFFER_CB_SUSPENDED 0x00010000
/* Flag set if we should invoke the callback on wakeup. */
#define EVBUFFER_CB_CALL_ON_UNSUSPEND 0x00020000
#endif
/* Flag set if the callback is using the cb_obsolete function pointer */
#define EVBUFFER_CB_OBSOLETE 0x00040000
@ -334,11 +327,23 @@ evbuffer_set_parent(struct evbuffer *buf, struct bufferevent *bev)
}
static void
evbuffer_run_callbacks(struct evbuffer *buffer)
evbuffer_run_callbacks(struct evbuffer *buffer, int running_deferred)
{
struct evbuffer_cb_entry *cbent, *next;
struct evbuffer_cb_info info;
size_t new_size;
uint32_t mask, masked_val;
if (running_deferred) {
mask = EVBUFFER_CB_NODEFER|EVBUFFER_CB_ENABLED;
masked_val = EVBUFFER_CB_ENABLED;
} else if (buffer->deferred_cbs) {
mask = EVBUFFER_CB_NODEFER|EVBUFFER_CB_ENABLED;
masked_val = EVBUFFER_CB_NODEFER|EVBUFFER_CB_ENABLED;
} else {
mask = EVBUFFER_CB_ENABLED;
masked_val = EVBUFFER_CB_ENABLED;
}
ASSERT_EVBUFFER_LOCKED(buffer);
@ -362,18 +367,15 @@ evbuffer_run_callbacks(struct evbuffer *buffer)
/* Get the 'next' pointer now in case this callback decides
* to remove itself or something. */
next = TAILQ_NEXT(cbent, next);
if ((cbent->flags & EVBUFFER_CB_ENABLED)) {
#if 0
if ((cbent->flags & EVBUFFER_CB_SUSPENDED))
cbent->flags |= EVBUFFER_CB_CALL_ON_UNSUSPEND;
else
#endif
if ((cbent->flags & EVBUFFER_CB_OBSOLETE))
cbent->cb.cb_obsolete(buffer,
info.orig_size, new_size, cbent->cbarg);
else
cbent->cb.cb_func(buffer, &info, cbent->cbarg);
}
if ((cbent->flags & mask) != masked_val)
continue;
if ((cbent->flags & EVBUFFER_CB_OBSOLETE))
cbent->cb.cb_obsolete(buffer,
info.orig_size, new_size, cbent->cbarg);
else
cbent->cb.cb_func(buffer, &info, cbent->cbarg);
}
}
@ -388,9 +390,9 @@ evbuffer_invoke_callbacks(struct evbuffer *buffer)
bufferevent_incref(buffer->parent);
EVBUFFER_UNLOCK(buffer);
event_deferred_cb_schedule(buffer->cb_queue, &buffer->deferred);
} else {
evbuffer_run_callbacks(buffer);
}
evbuffer_run_callbacks(buffer, 0);
}
static void
@ -403,7 +405,7 @@ evbuffer_deferred_callback(struct deferred_cb *cb, void *arg)
* lock */
EVBUFFER_LOCK(buffer);
parent = buffer->parent;
evbuffer_run_callbacks(buffer);
evbuffer_run_callbacks(buffer, 1);
_evbuffer_decref_and_unlock(buffer);
if (parent)
bufferevent_free(parent);

View File

@ -443,8 +443,8 @@ bufferevent_setwatermark(struct bufferevent *bufev, short events,
bufev);
}
evbuffer_cb_set_flags(bufev->input,
bufev_private->read_watermarks_cb,
EVBUFFER_CB_ENABLED);
bufev_private->read_watermarks_cb,
EVBUFFER_CB_ENABLED|EVBUFFER_CB_NODEFER);
if (evbuffer_get_length(bufev->input) > highmark)
bufferevent_wm_suspend_read(bufev);

View File

@ -610,6 +610,9 @@ int evbuffer_remove_cb(struct evbuffer *buffer, evbuffer_cb_func cb, void *cbarg
* should not be invoked. */
#define EVBUFFER_CB_ENABLED 1
/* Experimental cb flag: "never deferred" */
#define EVBUFFER_CB_NODEFER 2
/** Change the flags that are set for a callback on a buffer by adding more.
@param buffer the evbuffer that the callback is watching.