be_async_ctrl,
};
+static inline void
+be_async_run_eventcb(struct bufferevent *bev, short what, int options)
+{ bufferevent_run_eventcb_(bev, what, options|BEV_TRIG_DEFER_CALLBACKS); }
+
+static inline void
+be_async_trigger_nolock(struct bufferevent *bev, short what, int options)
+{ bufferevent_trigger_nolock_(bev, what, options|BEV_TRIG_DEFER_CALLBACKS); }
+
+static inline int
+fatal_error(int err)
+{
+ switch (err) {
+ /* We may have already associated this fd with a port.
+ * Let's hope it's this port, and that the error code
+ * for doing this neer changes. */
+ case ERROR_INVALID_PARAMETER:
+ return 0;
+ }
+ return 1;
+}
+
static inline struct bufferevent_async *
upcast(struct bufferevent *bev)
{
&beva->write_overlapped)) {
bufferevent_decref_(bev);
beva->ok = 0;
- bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR, 0);
+ be_async_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, 0);
+ be_async_run_eventcb(bev, BEV_EVENT_ERROR, 0);
bufferevent_decref_(bev);
} else {
beva->read_in_progress = at_most;
else
bev_async_set_wsa_error(bev, eo);
- bufferevent_run_eventcb_(bev,
- ok? BEV_EVENT_CONNECTED : BEV_EVENT_ERROR, 0);
+ be_async_run_eventcb(bev, ok ? BEV_EVENT_CONNECTED : BEV_EVENT_ERROR, 0);
event_base_del_virtual_(bev->ev_base);
if (bev_a->ok) {
if (ok && nbytes) {
BEV_RESET_GENERIC_READ_TIMEOUT(bev);
- bufferevent_trigger_nolock_(bev, EV_READ, 0);
+ be_async_trigger_nolock(bev, EV_READ, 0);
bev_async_consider_reading(bev_a);
} else if (!ok) {
what |= BEV_EVENT_ERROR;
bev_a->ok = 0;
- bufferevent_run_eventcb_(bev, what, 0);
+ be_async_run_eventcb(bev, what, 0);
} else if (!nbytes) {
what |= BEV_EVENT_EOF;
bev_a->ok = 0;
- bufferevent_run_eventcb_(bev, what, 0);
+ be_async_run_eventcb(bev, what, 0);
}
}
if (bev_a->ok) {
if (ok && nbytes) {
BEV_RESET_GENERIC_WRITE_TIMEOUT(bev);
- bufferevent_trigger_nolock_(bev, EV_WRITE, 0);
+ be_async_trigger_nolock(bev, EV_WRITE, 0);
bev_async_consider_writing(bev_a);
} else if (!ok) {
what |= BEV_EVENT_ERROR;
bev_a->ok = 0;
- bufferevent_run_eventcb_(bev, what, 0);
+ be_async_run_eventcb(bev, what, 0);
} else if (!nbytes) {
what |= BEV_EVENT_EOF;
bev_a->ok = 0;
- bufferevent_run_eventcb_(bev, what, 0);
+ be_async_run_eventcb(bev, what, 0);
}
}
return NULL;
if (fd >= 0 && event_iocp_port_associate_(iocp, fd, 1)<0) {
- int err = GetLastError();
- /* We may have alrady associated this fd with a port.
- * Let's hope it's this port, and that the error code
- * for doing this neer changes. */
- if (err != ERROR_INVALID_PARAMETER)
+ if (fatal_error(GetLastError()))
return NULL;
}
{
struct bufferevent_async *bev_async = upcast(bev);
bev_async->ok = 1;
- bufferevent_init_generic_timeout_cbs_(bev);
/* Now's a good time to consider reading/writing */
be_async_enable(bev, bev->enabled);
}
data->fd = evbuffer_overlapped_get_fd_(bev->input);
return 0;
case BEV_CTRL_SET_FD: {
+ struct bufferevent_async *bev_a = upcast(bev);
struct event_iocp_port *iocp;
if (data->fd == evbuffer_overlapped_get_fd_(bev->input))
return 0;
if (!(iocp = event_base_get_iocp_(bev->ev_base)))
return -1;
- if (event_iocp_port_associate_(iocp, data->fd, 1) < 0)
- return -1;
+ if (event_iocp_port_associate_(iocp, data->fd, 1) < 0) {
+ if (fatal_error(GetLastError()))
+ return -1;
+ }
evbuffer_overlapped_set_fd_(bev->input, data->fd);
evbuffer_overlapped_set_fd_(bev->output, data->fd);
+ bev_a->ok = data->fd >= 0;
return 0;
}
case BEV_CTRL_CANCEL_ALL: {