From: Nick Mathewson Date: Tue, 5 May 2009 14:18:14 +0000 (+0000) Subject: Add a constructor for bufferevent_async. X-Git-Tag: release-2.0.3-alpha~239 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b69d03b5a8eaf906575d44615e5bf0cab6fbe66a;p=libevent Add a constructor for bufferevent_async. svn:r1274 --- diff --git a/bufferevent.c b/bufferevent.c index 980d1468..553c37e3 100644 --- a/bufferevent.c +++ b/bufferevent.c @@ -203,12 +203,16 @@ bufferevent_init_common(struct bufferevent_private *bufev_private, { struct bufferevent *bufev = &bufev_private->bev; - if ((bufev->input = evbuffer_new()) == NULL) - return -1; + if (!bufev->input) { + if ((bufev->input = evbuffer_new()) == NULL) + return -1; + } - if ((bufev->output = evbuffer_new()) == NULL) { - evbuffer_free(bufev->input); - return -1; + if (!bufev->output) { + if ((bufev->output = evbuffer_new()) == NULL) { + evbuffer_free(bufev->input); + return -1; + } } bufev_private->refcnt = 1; diff --git a/bufferevent_async.c b/bufferevent_async.c index 2889ce95..3f641bff 100644 --- a/bufferevent_async.c +++ b/bufferevent_async.c @@ -67,7 +67,7 @@ static void be_async_adj_timeouts(struct bufferevent *); static int be_async_flush(struct bufferevent *, short, enum bufferevent_flush_mode); const struct bufferevent_ops bufferevent_ops_async = { - "socket", + "socket_async", 0, be_async_enable, be_async_disable, @@ -229,3 +229,50 @@ be_async_flush(struct bufferevent *bev, short what, { return 0; } + +struct bufferevent * +bufferevent_async_new(struct event_base *base, + evutil_socket_t fd, enum bufferevent_options options); + +struct bufferevent * +bufferevent_async_new(struct event_base *base, + evutil_socket_t fd, enum bufferevent_options options) +{ + struct bufferevent_async *bev_a; + struct bufferevent *bev; + struct event_iocp_port *iocp; + + options |= BEV_OPT_THREADSAFE; + + if (!(iocp = event_base_get_iocp(base))) + return NULL; + + if (event_iocp_port_associate(iocp, fd, 1)<0) + return NULL; + + if (!(bev_a = mm_calloc(1, sizeof(struct bufferevent_async)))) + return NULL; + + bev = &bev_a->bev.bev; + if (!(bev->input = evbuffer_overlapped_new(fd))) { + mm_free(bev_a); + return NULL; + } + if (!(bev->output = evbuffer_overlapped_new(fd))) { + evbuffer_free(bev->input); + mm_free(bev_a); + return NULL; + } + + if (bufferevent_init_common(&bev_a->bev, base, &bufferevent_ops_async, + options)<0) + goto err; + + evbuffer_add_cb(bev->input, be_async_inbuf_callback, bev); + evbuffer_add_cb(bev->output, be_async_outbuf_callback, bev); + + return bev; +err: + bufferevent_free(&bev_a->bev.bev); + return NULL; +} diff --git a/event-internal.h b/event-internal.h index 519223e0..7a6bf8c6 100644 --- a/event-internal.h +++ b/event-internal.h @@ -154,6 +154,10 @@ struct event_base { void *th_base_lock; #endif +#ifdef WIN32 + struct event_iocp_port *iocp; +#endif + /* Notify main thread to wake up break, etc. */ int th_notify_fd[2]; struct event th_notify; diff --git a/event_iocp.c b/event_iocp.c index 32d44629..18021aaa 100644 --- a/event_iocp.c +++ b/event_iocp.c @@ -194,3 +194,14 @@ event_iocp_activate_overlapped( r = PostQueuedCompletionStatus(port->port, n, key, &o->overlapped); return (r==0) ? -1 : 0; } + +struct event_iocp * +event_base_get_iocp(struct event_base *base) +{ +#ifdef WIN32 + return base->iocp; +#else + return NULL +#endif +} + diff --git a/iocp-internal.h b/iocp-internal.h index de731155..1dcdbc23 100644 --- a/iocp-internal.h +++ b/iocp-internal.h @@ -145,6 +145,7 @@ int event_iocp_activate_overlapped(struct event_iocp_port *port, struct event_overlapped *o, uintptr_t key, ev_uint32_t n_bytes); +struct event_iocp_port *event_base_get_iocp(struct event_base *base); #ifdef __cplusplus }