* a writecb. Otherwise just run the writecb. */
void bufferevent_run_writecb_(struct bufferevent *bufev, int options);
/** Internal: If callbacks are deferred and we have an eventcb, schedule
- * it to run with events "what". Otherwise just run the eventcb. */
-void bufferevent_run_eventcb_(struct bufferevent *bufev, short what);
+ * it to run with events "what". Otherwise just run the eventcb.
+ * See bufferevent_trigger_event for meaning of "options". */
+void bufferevent_run_eventcb_(struct bufferevent *bufev, short what, int options);
/** Internal: Run or schedule (if deferred or options contain
* BEV_TRIG_DEFER_CALLBACKS) I/O callbacks specified in iotype.
}
void
-bufferevent_run_eventcb_(struct bufferevent *bufev, short what)
+bufferevent_run_eventcb_(struct bufferevent *bufev, short what, int options)
{
/* Requires that we hold the lock and a reference */
struct bufferevent_private *p =
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
if (bufev->errorcb == NULL)
return;
- if (p->options & BEV_OPT_DEFER_CALLBACKS) {
+ if ((p->options & BEV_OPT_DEFER_CALLBACKS) ||
+ (options & BEV_TRIG_DEFER_CALLBACKS)) {
p->eventcb_pending |= what;
p->errno_pending = EVUTIL_SOCKET_ERROR();
SCHEDULE_DEFERRED(p);
}
}
+void
+bufferevent_trigger_event(struct bufferevent *bufev, short what, int options)
+{
+ bufferevent_incref_and_lock_(bufev);
+ bufferevent_run_eventcb_(bufev, what, options);
+ bufferevent_decref_and_unlock_(bufev);
+}
+
int
bufferevent_init_common_(struct bufferevent_private *bufev_private,
struct event_base *base,
struct bufferevent *bev = ctx;
bufferevent_incref_and_lock_(bev);
bufferevent_disable(bev, EV_READ);
- bufferevent_run_eventcb_(bev, BEV_EVENT_TIMEOUT|BEV_EVENT_READING);
+ bufferevent_run_eventcb_(bev, BEV_EVENT_TIMEOUT|BEV_EVENT_READING, 0);
bufferevent_decref_and_unlock_(bev);
}
static void
struct bufferevent *bev = ctx;
bufferevent_incref_and_lock_(bev);
bufferevent_disable(bev, EV_WRITE);
- bufferevent_run_eventcb_(bev, BEV_EVENT_TIMEOUT|BEV_EVENT_WRITING);
+ bufferevent_run_eventcb_(bev, BEV_EVENT_TIMEOUT|BEV_EVENT_WRITING, 0);
bufferevent_decref_and_unlock_(bev);
}
&beva->write_overlapped)) {
bufferevent_decref_(bev);
beva->ok = 0;
- bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR);
+ bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR, 0);
} else {
beva->write_in_progress = at_most;
bufferevent_decrement_write_buckets_(&beva->bev, at_most);
bufferevent_incref_(bev);
if (evbuffer_launch_read_(bev->input, at_most, &beva->read_overlapped)) {
beva->ok = 0;
- bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR);
+ bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR, 0);
bufferevent_decref_(bev);
} else {
beva->read_in_progress = at_most;
bev_async_set_wsa_error(bev, eo);
bufferevent_run_eventcb_(bev,
- ok? BEV_EVENT_CONNECTED : BEV_EVENT_ERROR);
+ ok? BEV_EVENT_CONNECTED : BEV_EVENT_ERROR, 0);
event_base_del_virtual_(bev->ev_base);
} else if (!ok) {
what |= BEV_EVENT_ERROR;
bev_a->ok = 0;
- bufferevent_run_eventcb_(bev, what);
+ bufferevent_run_eventcb_(bev, what, 0);
} else if (!nbytes) {
what |= BEV_EVENT_EOF;
bev_a->ok = 0;
- bufferevent_run_eventcb_(bev, what);
+ bufferevent_run_eventcb_(bev, what, 0);
}
}
} else if (!ok) {
what |= BEV_EVENT_ERROR;
bev_a->ok = 0;
- bufferevent_run_eventcb_(bev, what);
+ bufferevent_run_eventcb_(bev, what, 0);
} else if (!nbytes) {
what |= BEV_EVENT_EOF;
bev_a->ok = 0;
- bufferevent_run_eventcb_(bev, what);
+ bufferevent_run_eventcb_(bev, what, 0);
}
}
bufferevent_incref_and_lock_(bev);
/* All we can really to is tell our own eventcb. */
- bufferevent_run_eventcb_(bev, what);
+ bufferevent_run_eventcb_(bev, what, 0);
bufferevent_decref_and_unlock_(bev);
}
/* when is BEV_EVENT_{READING|WRITING} */
event = when | event;
- bufferevent_run_eventcb_(&bev_ssl->bev.bev, event);
+ bufferevent_run_eventcb_(&bev_ssl->bev.bev, event, 0);
}
static void
eat it. */
}
if (event)
- bufferevent_run_eventcb_(&bev_ssl->bev.bev, event);
+ bufferevent_run_eventcb_(&bev_ssl->bev.bev, event, 0);
}
static void
bufferevent_incref_and_lock_(&bev_ssl->bev.bev);
if (what == EV_TIMEOUT) {
bufferevent_run_eventcb_(&bev_ssl->bev.bev,
- BEV_EVENT_TIMEOUT|BEV_EVENT_READING);
+ BEV_EVENT_TIMEOUT|BEV_EVENT_READING, 0);
} else {
consider_reading(bev_ssl);
}
bufferevent_incref_and_lock_(&bev_ssl->bev.bev);
if (what == EV_TIMEOUT) {
bufferevent_run_eventcb_(&bev_ssl->bev.bev,
- BEV_EVENT_TIMEOUT|BEV_EVENT_WRITING);
+ BEV_EVENT_TIMEOUT|BEV_EVENT_WRITING, 0);
} else {
consider_writing(bev_ssl);
}
/* Call do_read and do_write as needed */
bufferevent_enable(&bev_ssl->bev.bev, bev_ssl->bev.bev.enabled);
bufferevent_run_eventcb_(&bev_ssl->bev.bev,
- BEV_EVENT_CONNECTED);
+ BEV_EVENT_CONNECTED, 0);
return 1;
} else {
int err = SSL_get_error(bev_ssl->ssl, r);
bufferevent_incref_and_lock_(&bev_ssl->bev.bev);
if (what & EV_TIMEOUT) {
- bufferevent_run_eventcb_(&bev_ssl->bev.bev, BEV_EVENT_TIMEOUT);
+ bufferevent_run_eventcb_(&bev_ssl->bev.bev, BEV_EVENT_TIMEOUT, 0);
} else
do_handshake(bev_ssl);/* XXX handle failure */
bufferevent_decref_and_unlock_(&bev_ssl->bev.bev);
be_pair_transfer(bev, partner, 1);
if (mode == BEV_FINISHED) {
- bufferevent_run_eventcb_(partner, iotype|BEV_EVENT_EOF);
+ bufferevent_run_eventcb_(partner, iotype|BEV_EVENT_EOF, 0);
}
decref_and_unlock(bev);
return 0;
error:
bufferevent_disable(bufev, EV_READ);
- bufferevent_run_eventcb_(bufev, what);
+ bufferevent_run_eventcb_(bufev, what, 0);
done:
bufferevent_decref_and_unlock_(bufev);
if (c < 0) {
event_del(&bufev->ev_write);
event_del(&bufev->ev_read);
- bufferevent_run_eventcb_(bufev, BEV_EVENT_ERROR);
+ bufferevent_run_eventcb_(bufev, BEV_EVENT_ERROR, 0);
goto done;
} else {
connected = 1;
event_del(&bufev->ev_write);
bufferevent_async_set_connected_(bufev);
bufferevent_run_eventcb_(bufev,
- BEV_EVENT_CONNECTED);
+ BEV_EVENT_CONNECTED, 0);
goto done;
}
#endif
bufferevent_run_eventcb_(bufev,
- BEV_EVENT_CONNECTED);
+ BEV_EVENT_CONNECTED, 0);
if (!(bufev->enabled & EV_WRITE) ||
bufev_p->write_suspended) {
event_del(&bufev->ev_write);
error:
bufferevent_disable(bufev, EV_WRITE);
- bufferevent_run_eventcb_(bufev, what);
+ bufferevent_run_eventcb_(bufev, what, 0);
done:
bufferevent_decref_and_unlock_(bufev);
goto done;
freesock:
- bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR);
+ bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR, 0);
if (ownfd)
evutil_closesocket(fd);
/* do something about the error? */
if (result != 0) {
bev_p->dns_error = result;
- bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR);
+ bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR, 0);
bufferevent_decref_and_unlock_(bev);
if (ai)
evutil_freeaddrinfo(ai);
void bufferevent_trigger(struct bufferevent *bufev, short iotype,
int options);
+/**
+ Triggers the bufferevent event callback.
+
+ If the options contain BEV_OPT_DEFER_CALLBACKS, the callbacks are deferred.
+
+ @param bufev the bufferevent object
+ @param what the flags to pass onto the event callback
+ @param options
+ */
+void bufferevent_trigger_event(struct bufferevent *bufev, short what,
+ int options);
+
/**
@name Filtering support
}
static void
-trigger_readcb_triggered(struct bufferevent *bev, void *ctx)
+trigger_eventcb(struct bufferevent *bev, short what, void *ctx)
{
struct event_base *base = ctx;
+ if (what == ~0) {
+ TT_BLATHER(("Event successfully triggered."));
+ event_base_loopexit(base, NULL);
+ return;
+ }
+ reader_eventcb(bev, what, ctx);
+}
+static void
+trigger_readcb_triggered(struct bufferevent *bev, void *ctx)
+{
TT_BLATHER(("Read successfully triggered."));
n_reads_invoked++;
- event_base_loopexit(base, NULL);
+ bufferevent_trigger_event(bev, ~0, bufferevent_trigger_test_flags);
}
static void
TT_BLATHER(("Read invoked on %d.", (int)bufferevent_getfd(bev)));
expected_reads = ++n_reads_invoked;
- bufferevent_setcb(bev, trigger_readcb_triggered, NULL, reader_eventcb, ctx);
+ bufferevent_setcb(bev, trigger_readcb_triggered, NULL, trigger_eventcb, ctx);
bufferevent_getwatermark(bev, EV_READ, &low, &high);
len = evbuffer_get_length(bufferevent_get_input(bev));
tt_assert(!evconnlistener_enable(lev));
bev = bufferevent_socket_new(data->base, -1, be_flags);
tt_assert(bev);
- bufferevent_setcb(bev, trigger_readcb, NULL, reader_eventcb, data->base);
+ bufferevent_setcb(bev, trigger_readcb, NULL, trigger_eventcb, data->base);
bufferevent_enable(bev, EV_READ);