]> granicus.if.org Git - libevent/commitdiff
Add a constructor for bufferevent_async.
authorNick Mathewson <nickm@torproject.org>
Tue, 5 May 2009 14:18:14 +0000 (14:18 +0000)
committerNick Mathewson <nickm@torproject.org>
Tue, 5 May 2009 14:18:14 +0000 (14:18 +0000)
svn:r1274

bufferevent.c
bufferevent_async.c
event-internal.h
event_iocp.c
iocp-internal.h

index 980d1468ddd2879a5b6ba821bcbf1d854009d1c7..553c37e3f8974aeffe134eddaa579b2a8445c716 100644 (file)
@@ -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;
index 2889ce9507ccc5c4df205abd932a773706fd75d1..3f641bffe22cda39def12a67247a6132b4ded9c3 100644 (file)
@@ -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;
+}
index 519223e0e42cc2fef3643f818445baa8c39a8715..7a6bf8c6edb59d8fbd07b3ed3a4bc7f32a1db290 100644 (file)
@@ -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;
index 32d446292e2d84b0def95d102d1edcff3af7f10e..18021aaa071dee43d925ab62e95f2f78541bb47a 100644 (file)
@@ -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
+}
+
index de7311559422324b09eafb2005be418ed7e0a26e..1dcdbc239e1ff19e9643aea01c36c1a16ccfe4c0 100644 (file)
@@ -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
 }