]> granicus.if.org Git - libevent/commitdiff
Refactor new elements of bufferevent into bufferevent_private structure
authorNick Mathewson <nickm@torproject.org>
Mon, 13 Apr 2009 03:08:11 +0000 (03:08 +0000)
committerNick Mathewson <nickm@torproject.org>
Mon, 13 Apr 2009 03:08:11 +0000 (03:08 +0000)
This way we don't expose more of a bufferevent than we need to.  One
motivation is to make it easier to automatically get deferred callbacks
with a bufferevent without exposing the deferred_cb structure.

svn:r1169

bufferevent-internal.h
bufferevent.c
bufferevent_filter.c
bufferevent_pair.c
bufferevent_sock.c
include/event2/bufferevent_struct.h

index 1d4b80d10611a2a805073819aaf3b2da9b8353ee..f369659ffa606fcd0f734f2239f1deca59f0bf85 100644 (file)
@@ -32,6 +32,22 @@ extern "C" {
 
 #include "event-config.h"
 #include "evutil.h"
+#include "defer-internal.h"
+
+struct bufferevent_private {
+       struct bufferevent bev;
+
+       /** Evbuffer callback to enforce watermarks on input. */
+       struct evbuffer_cb_entry *read_watermarks_cb;
+
+       /** If set, read is suspended until evbuffer some. */
+       unsigned read_suspended : 1;
+
+       enum bufferevent_options options;
+
+       int refcnt;
+       void *lock;
+};
 
 /**
    Implementation table for a bufferevent: holds function pointers and other
@@ -81,7 +97,7 @@ extern const struct bufferevent_ops bufferevent_ops_filter;
 extern const struct bufferevent_ops bufferevent_ops_pair;
 
 /** Initialize the shared parts of a bufferevent. */
-int bufferevent_init_common(struct bufferevent *, struct event_base *, const struct bufferevent_ops *, enum bufferevent_options options);
+int bufferevent_init_common(struct bufferevent_private *, struct event_base *, const struct bufferevent_ops *, enum bufferevent_options options);
 
 /** For internal use: temporarily stop all reads on bufev, because its
  * read buffer is too full. */
index 53459a29a4de86a48fa56d94c9da32382aaa0b29..69b8670243b6c6326664a5e6368f4133975edc32 100644 (file)
 void
 bufferevent_wm_suspend_read(struct bufferevent *bufev)
 {
-       if (!bufev->read_suspended) {
+       struct bufferevent_private *bufev_private =
+           EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
+       if (!bufev_private->read_suspended) {
                bufev->be_ops->disable(bufev, EV_READ);
-               bufev->read_suspended = 1;
+               bufev_private->read_suspended = 1;
        }
 }
 
 void
 bufferevent_wm_unsuspend_read(struct bufferevent *bufev)
 {
-       if (bufev->read_suspended) {
-               bufev->read_suspended = 0;
+       struct bufferevent_private *bufev_private =
+           EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
+       if (bufev_private->read_suspended) {
+               bufev_private->read_suspended = 0;
                if (bufev->enabled & EV_READ)
                        bufev->be_ops->enable(bufev, EV_READ);
        }
@@ -103,10 +107,13 @@ bufferevent_inbuf_wm_cb(struct evbuffer *buf,
 }
 
 int
-bufferevent_init_common(struct bufferevent *bufev, struct event_base *base,
-                       const struct bufferevent_ops *ops,
-                       enum bufferevent_options options)
+bufferevent_init_common(struct bufferevent_private *bufev_private,
+    struct event_base *base,
+    const struct bufferevent_ops *ops,
+    enum bufferevent_options options)
 {
+       struct bufferevent *bufev = &bufev_private->bev;
+
        if ((bufev->input = evbuffer_new()) == NULL)
                return -1;
 
@@ -130,7 +137,7 @@ bufferevent_init_common(struct bufferevent *bufev, struct event_base *base,
         */
        bufev->enabled = EV_WRITE;
 
-       bufev->options = options;
+       bufev_private->options = options;
 
        return 0;
 }
@@ -196,8 +203,10 @@ bufferevent_read_buffer(struct bufferevent *bufev, struct evbuffer *buf)
 int
 bufferevent_enable(struct bufferevent *bufev, short event)
 {
+       struct bufferevent_private *bufev_private =
+           EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
        short impl_events = event;
-       if (bufev->read_suspended)
+       if (bufev_private->read_suspended)
                impl_events &= ~EV_READ;
 
        bufev->enabled |= event;
@@ -272,6 +281,8 @@ void
 bufferevent_setwatermark(struct bufferevent *bufev, short events,
     size_t lowmark, size_t highmark)
 {
+       struct bufferevent_private *bufev_private =
+           EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
 
        if (events & EV_WRITE) {
                bufev->wm_write.low = lowmark;
@@ -287,14 +298,14 @@ bufferevent_setwatermark(struct bufferevent *bufev, short events,
                           enable the callback if needed, and see if we should
                           suspend/bufferevent_wm_unsuspend. */
 
-                       if (bufev->read_watermarks_cb == NULL) {
-                               bufev->read_watermarks_cb =
+                       if (bufev_private->read_watermarks_cb == NULL) {
+                               bufev_private->read_watermarks_cb =
                                    evbuffer_add_cb(bufev->input,
                                                    bufferevent_inbuf_wm_cb,
                                                    bufev);
                        }
                        evbuffer_cb_set_flags(bufev->input,
-                                             bufev->read_watermarks_cb,
+                                             bufev_private->read_watermarks_cb,
                                              EVBUFFER_CB_ENABLED);
 
                        if (EVBUFFER_LENGTH(bufev->input) > highmark)
@@ -303,10 +314,10 @@ bufferevent_setwatermark(struct bufferevent *bufev, short events,
                                bufferevent_wm_unsuspend_read(bufev);
                } else {
                        /* There is now no high-water mark for read. */
-                       if (bufev->read_watermarks_cb)
+                       if (bufev_private->read_watermarks_cb)
                                evbuffer_cb_set_flags(bufev->input,
-                                                     bufev->read_watermarks_cb,
-                                                     EVBUFFER_CB_DISABLED);
+                                   bufev_private->read_watermarks_cb,
+                                   EVBUFFER_CB_DISABLED);
                        bufferevent_wm_unsuspend_read(bufev);
                }
        }
index fcd090be0488cffe549300d848be94c5817bfb54..54fd23c828b732fbfb37399a4a0ededd155bfc99 100644 (file)
@@ -76,7 +76,7 @@ static void bufferevent_filtered_outbuf_cb(struct evbuffer *buf,
     const struct evbuffer_cb_info *info, void *arg);
 
 struct bufferevent_filtered {
-       struct bufferevent bev;
+       struct bufferevent_private bev;
 
         /** The bufferevent that we read/write filterd data from/to. */
        struct bufferevent *underlying;
@@ -116,12 +116,12 @@ upcast(struct bufferevent *bev)
        if (bev->be_ops != &bufferevent_ops_filter)
                return NULL;
        bev_f = (void*)( ((char*)bev) -
-                        evutil_offsetof(struct bufferevent_filtered, bev);
-       assert(bev_f->bev.be_ops == &bufferevent_ops_filter);
+                        evutil_offsetof(struct bufferevent_filtered, bev.bev));
+       assert(bev_f->bev.bev.be_ops == &bufferevent_ops_filter);
        return bev_f;
 }
 
-#define downcast(bev_f) (&(bev_f)->bev)
+#define downcast(bev_f) (&(bev_f)->bev.bev)
 
 /** Return 1 iff bevf's underlying bufferevent's output buffer is at or
  * over its high watermark such that we should not write to it in a given
@@ -195,10 +195,10 @@ bufferevent_filter_new(struct bufferevent *underlying,
        bufferevent_setcb(bufev_f->underlying,
             be_filter_readcb, be_filter_writecb, be_filter_errorcb, bufev_f);
 
-       bufev_f->outbuf_cb = evbuffer_add_cb(bufev_f->bev.output,
+       bufev_f->outbuf_cb = evbuffer_add_cb(downcast(bufev_f)->output,
           bufferevent_filtered_outbuf_cb, bufev_f);
 
-       return &bufev_f->bev;
+       return downcast(bufev_f);
 }
 
 static void
@@ -209,7 +209,7 @@ be_filter_destruct(struct bufferevent *bev)
        if (bevf->free_context)
                bevf->free_context(bevf->context);
 
-       if (bev->options & BEV_OPT_CLOSE_ON_FREE)
+       if (bevf->bev.options & BEV_OPT_CLOSE_ON_FREE)
                bufferevent_free(bevf->underlying);
 }
 
@@ -247,28 +247,29 @@ be_filter_process_input(struct bufferevent_filtered *bevf,
                        int *processed_out)
 {
        enum bufferevent_filter_result res;
+       struct bufferevent *bev = downcast(bevf);
 
         if (state == BEV_NORMAL) {
                 /* If we're in 'normal' mode, don't urge data on the filter
                  * unless we're reading data and under our high-water mark.*/
-                if (!(bevf->bev.enabled & EV_READ) ||
+                if (!(bev->enabled & EV_READ) ||
                     be_readbuf_full(bevf, state))
                         return BEV_OK;
         }
 
        do {
                 ssize_t limit = -1;
-                if (state == BEV_NORMAL && bevf->bev.wm_read.high)
-                        limit = bevf->bev.wm_read.high -
-                            EVBUFFER_LENGTH(bevf->bev.input);
+                if (state == BEV_NORMAL && bev->wm_read.high)
+                        limit = bev->wm_read.high -
+                            EVBUFFER_LENGTH(bev->input);
 
                res = bevf->process_in(bevf->underlying->input,
-                    bevf->bev.input, limit, state, bevf->context);
+                    bev->input, limit, state, bevf->context);
 
                if (res == BEV_OK)
                        *processed_out = 1;
        } while (res == BEV_OK &&
-                (bevf->bev.enabled & EV_READ) &&
+                (bev->enabled & EV_READ) &&
                 EVBUFFER_LENGTH(bevf->underlying->input) &&
                 !be_readbuf_full(bevf, state));
 
@@ -312,7 +313,7 @@ be_filter_process_output(struct bufferevent_filtered *bevf,
                                 limit = bevf->underlying->wm_write.high -
                                     EVBUFFER_LENGTH(bevf->underlying->output);
 
-                        res = bevf->process_out(bevf->bev.output,
+                        res = bevf->process_out(downcast(bevf)->output,
                             bevf->underlying->output,
                             limit,
                             state,
@@ -405,10 +406,11 @@ static void
 be_filter_errorcb(struct bufferevent *underlying, short what, void *_me)
 {
        struct bufferevent_filtered *bevf = _me;
+       struct bufferevent *bev = downcast(bevf);
 
        /* All we can really to is tell our own errorcb. */
-       if (bevf->bev.errorcb)
-               bevf->bev.errorcb(&bevf->bev, what, bevf->bev.cbarg);
+       if (bev->errorcb)
+               bev->errorcb(bev, what, bev->cbarg);
 }
 
 static int
index 2551d3de6ff98358db68bfbd321161af05fa5852..6fed0e0331ad5b6b59e85db1ebd7f1209a7488b6 100644 (file)
@@ -42,7 +42,7 @@
 #include "util-internal.h"
 
 struct bufferevent_pair {
-       struct bufferevent bev;
+       struct bufferevent_private bev;
        struct bufferevent_pair *partner;
        struct deferred_cb deferred_write_cb;
        struct deferred_cb deferred_read_cb;
@@ -57,12 +57,12 @@ upcast(struct bufferevent *bev)
        struct bufferevent_pair *bev_p;
        if (bev->be_ops != &bufferevent_ops_pair)
                return NULL;
-       bev_p = EVUTIL_UPCAST(bev, struct bufferevent_pair, bev);
-       assert(bev_p->bev.be_ops == &bufferevent_ops_pair);
+       bev_p = EVUTIL_UPCAST(bev, struct bufferevent_pair, bev.bev);
+       assert(bev_p->bev.bev.be_ops == &bufferevent_ops_pair);
        return bev_p;
 }
 
-#define downcast(bev_pair) (&(bev_pair)->bev)
+#define downcast(bev_pair) (&(bev_pair)->bev.bev)
 
 /* XXX Handle close */
 
@@ -100,7 +100,7 @@ bufferevent_pair_elt_new(struct event_base *base,
        }
        /* XXX set read timeout event */
        /* XXX set write timeout event */
-       if (!evbuffer_add_cb(bufev->bev.output, be_pair_outbuf_cb, bufev)) {
+       if (!evbuffer_add_cb(bufev->bev.bev.output, be_pair_outbuf_cb, bufev)) {
                bufferevent_free(downcast(bufev));
                return NULL;
        }
@@ -128,10 +128,10 @@ bufferevent_pair_new(struct event_base *base, enum bufferevent_options options,
        bufev1->partner = bufev2;
        bufev2->partner = bufev1;
 
-       evbuffer_freeze(bufev1->bev.input, 0);
-       evbuffer_freeze(bufev1->bev.output, 1);
-       evbuffer_freeze(bufev2->bev.input, 0);
-       evbuffer_freeze(bufev2->bev.output, 1);
+       evbuffer_freeze(downcast(bufev1)->input, 0);
+       evbuffer_freeze(downcast(bufev1)->output, 1);
+       evbuffer_freeze(downcast(bufev2)->input, 0);
+       evbuffer_freeze(downcast(bufev2)->output, 1);
 
        pair[0] = downcast(bufev1);
        pair[1] = downcast(bufev2);
@@ -180,11 +180,13 @@ done:
 }
 
 static inline int
-be_pair_wants_to_talk(struct bufferevent *src, struct bufferevent *dst)
+be_pair_wants_to_talk(struct bufferevent_pair *src,
+    struct bufferevent_pair *dst)
 {
-       return (src->enabled & EV_WRITE) &&
-           (dst->enabled & EV_READ) && !dst->read_suspended &&
-           evbuffer_get_length(src->output);
+       return (downcast(src)->enabled & EV_WRITE) &&
+           (downcast(dst)->enabled & EV_READ) &&
+           !dst->bev.read_suspended &&
+           evbuffer_get_length(downcast(src)->output);
 }
 
 static void
@@ -197,8 +199,7 @@ be_pair_outbuf_cb(struct evbuffer *outbuf,
        if (info->n_added > info->n_deleted && partner) {
                /* We got more data.  If the other side's reading, then
                   hand it over. */
-               if (be_pair_wants_to_talk(downcast(bev_pair),
-                       downcast(partner))) {
+               if (be_pair_wants_to_talk(bev_pair, partner)) {
                        be_pair_transfer(downcast(bev_pair), downcast(partner), 0);
                }
        }
@@ -212,12 +213,12 @@ be_pair_enable(struct bufferevent *bufev, short events)
 
        /* We're starting to read! Does the other side have anything to write?*/
        if ((events & EV_READ) && partner &&
-           be_pair_wants_to_talk(downcast(partner), bufev)) {
+           be_pair_wants_to_talk(partner, bev_p)) {
                be_pair_transfer(downcast(partner), bufev, 0);
        }
        /* We're starting to write! Does the other side want to read? */
        if ((events & EV_WRITE) && partner &&
-           be_pair_wants_to_talk(bufev, downcast(partner))) {
+           be_pair_wants_to_talk(bev_p, partner)) {
                be_pair_transfer(bufev, downcast(partner), 0);
        }
        return 0;
index 561bec79e961a23bcd748ccc21772723fe827713..0e5e3a7b779269d5094182a153dbd0add582b88b 100644 (file)
@@ -225,16 +225,18 @@ struct bufferevent *
 bufferevent_socket_new(struct event_base *base, evutil_socket_t fd,
     enum bufferevent_options options)
 {
+       struct bufferevent_private *bufev_p;
        struct bufferevent *bufev;
 
-       if ((bufev = mm_calloc(1, sizeof(struct bufferevent))) == NULL)
+       if ((bufev_p = mm_calloc(1, sizeof(struct bufferevent_private)))== NULL)
                return NULL;
 
-       if (bufferevent_init_common(bufev, base, &bufferevent_ops_socket,
+       if (bufferevent_init_common(bufev_p, base, &bufferevent_ops_socket,
                                    options) < 0) {
-               mm_free(bufev);
+               mm_free(bufev_p);
                return NULL;
        }
+       bufev = &bufev_p->bev;
 
        event_assign(&bufev->ev_read, bufev->ev_base, fd,
            EV_READ|EV_PERSIST, bufferevent_readcb, bufev);
@@ -306,6 +308,8 @@ be_socket_disable(struct bufferevent *bufev, short event)
 static void
 be_socket_destruct(struct bufferevent *bufev)
 {
+       struct bufferevent_private *bufev_p =
+           EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
        evutil_socket_t fd;
        assert(bufev->be_ops == &bufferevent_ops_socket);
 
@@ -314,7 +318,7 @@ be_socket_destruct(struct bufferevent *bufev)
        event_del(&bufev->ev_read);
        event_del(&bufev->ev_write);
 
-       if (bufev->options & BEV_OPT_CLOSE_ON_FREE)
+       if (bufev_p->options & BEV_OPT_CLOSE_ON_FREE)
                EVUTIL_CLOSESOCKET(fd);
 }
 
index a667e89f1842b0980eb78ae714032bf3205fefd8..eb4a86e4e3eceb2afcd7817d67ee8edaeac0117e 100644 (file)
@@ -105,16 +105,9 @@ struct bufferevent {
        struct timeval timeout_read;
        struct timeval timeout_write;
 
-       /** Evbuffer callback to enforce watermarks on input. */
-       struct evbuffer_cb_entry *read_watermarks_cb;
-
        /** Events that are currently enabled: currently EV_READ and EV_WRITE
            are supported. */
        short enabled;
-       /** If set, read is suspended until evbuffer some. */
-       unsigned read_suspended : 1; /*  */
-
-       enum bufferevent_options options;
 };
 
 #ifdef __cplusplus