mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-13 22:37:42 -04:00
Facility to make evbuffers get their callbacks deferred.
svn:r1154
This commit is contained in:
parent
decdacfaf8
commit
b29b875d84
41
buffer.c
41
buffer.c
@ -134,6 +134,7 @@ static int use_mmap = 1;
|
||||
#define CHAIN_PINNED(ch) (((ch)->flags & EVBUFFER_MEM_PINNED_ANY) != 0)
|
||||
|
||||
static void evbuffer_chain_align(struct evbuffer_chain *chain);
|
||||
static void evbuffer_deferred_callback(struct deferred_cb *cb, void *arg);
|
||||
|
||||
static struct evbuffer_chain *
|
||||
evbuffer_chain_new(size_t size)
|
||||
@ -260,6 +261,18 @@ evbuffer_new(void)
|
||||
return (buffer);
|
||||
}
|
||||
|
||||
int
|
||||
evbuffer_defer_callbacks(struct evbuffer *buffer, struct event_base *base)
|
||||
{
|
||||
EVBUFFER_LOCK(buffer, EVTHREAD_WRITE);
|
||||
buffer->ev_base = base;
|
||||
buffer->deferred_cbs = 1;
|
||||
event_deferred_cb_init(&buffer->deferred,
|
||||
evbuffer_deferred_callback, buffer);
|
||||
EVBUFFER_UNLOCK(buffer, EVTHREAD_WRITE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
evbuffer_enable_locking(struct evbuffer *buf, void *lock)
|
||||
{
|
||||
@ -284,8 +297,8 @@ evbuffer_enable_locking(struct evbuffer *buf, void *lock)
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
evbuffer_invoke_callbacks(struct evbuffer *buffer)
|
||||
static void
|
||||
evbuffer_run_callbacks(struct evbuffer *buffer)
|
||||
{
|
||||
struct evbuffer_cb_entry *cbent, *next;
|
||||
struct evbuffer_cb_info info;
|
||||
@ -328,6 +341,28 @@ evbuffer_invoke_callbacks(struct evbuffer *buffer)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
evbuffer_invoke_callbacks(struct evbuffer *buffer)
|
||||
{
|
||||
if (buffer->deferred_cbs) {
|
||||
event_deferred_cb_schedule(buffer->ev_base, &buffer->deferred);
|
||||
} else {
|
||||
evbuffer_run_callbacks(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
evbuffer_deferred_callback(struct deferred_cb *cb, void *arg)
|
||||
{
|
||||
struct evbuffer *buffer = arg;
|
||||
static int which = 0;
|
||||
printf("FOO #%d\n", which++);
|
||||
|
||||
EVBUFFER_LOCK(buffer, EVTHREAD_WRITE);
|
||||
evbuffer_run_callbacks(buffer);
|
||||
EVBUFFER_UNLOCK(buffer, EVTHREAD_WRITE);
|
||||
}
|
||||
|
||||
static void
|
||||
evbuffer_remove_all_callbacks(struct evbuffer *buffer)
|
||||
{
|
||||
@ -351,6 +386,8 @@ evbuffer_free(struct evbuffer *buffer)
|
||||
evbuffer_chain_free(chain);
|
||||
}
|
||||
evbuffer_remove_all_callbacks(buffer);
|
||||
if (buffer->deferred_cbs)
|
||||
event_deferred_cb_cancel(buffer->ev_base, &buffer->deferred);
|
||||
if (buffer->own_lock)
|
||||
EVTHREAD_FREE_LOCK(buffer->lock);
|
||||
mm_free(buffer);
|
||||
|
@ -33,6 +33,7 @@ extern "C" {
|
||||
|
||||
#include "event-config.h"
|
||||
#include "evutil.h"
|
||||
#include "defer-internal.h"
|
||||
|
||||
#include <sys/queue.h>
|
||||
/* minimum allocation for a chain. */
|
||||
@ -78,9 +79,14 @@ struct evbuffer {
|
||||
unsigned own_lock : 1;
|
||||
unsigned freeze_start : 1;
|
||||
unsigned freeze_end : 1;
|
||||
unsigned deferred_cbs : 1;
|
||||
|
||||
struct event_base *ev_base;
|
||||
|
||||
int lock_count;
|
||||
|
||||
struct deferred_cb deferred;
|
||||
|
||||
TAILQ_HEAD(evbuffer_cb_queue, evbuffer_cb_entry) callbacks;
|
||||
};
|
||||
|
||||
|
@ -587,6 +587,16 @@ int evbuffer_freeze(struct evbuffer *buf, int at_front);
|
||||
*/
|
||||
int evbuffer_unfreeze(struct evbuffer *buf, int at_front);
|
||||
|
||||
struct event_base;
|
||||
/**
|
||||
Force all the callbacks on an evbuffer to be run, not immediately after
|
||||
the evbuffer is altered, but instead from inside the event loop.
|
||||
|
||||
This can be used to serialize all the callbacks to a single thread
|
||||
of execution.
|
||||
*/
|
||||
int evbuffer_defer_callbacks(struct evbuffer *buffer, struct event_base *base);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user