ok beck@

On Fri, Sep 18, 2015 at 5:17 PM, Alexander Bluhm
<alexander.bl...@gmx.net> wrote:
> On Fri, Sep 18, 2015 at 05:04:55PM -0600, Bob Beck wrote:
>> ... and just to be clear, you only need to event_del when you are
>> switching to wanting a write when you did want a read before, and vice
>> versa... correct?
>
> Yes.  When I am doing reads and get a TLS_WANT_POLLOUT, I have to
> do a event_set() on the write event to change the callback to read.
> As there might be an event scheduled on the event, I have to do an
> event_del() before event_set().
>
> That's why the changing case is a bit more complex.
>
> After success I have to change back the other event, so I need
> event_del() and event_set() again.
>
> bluhm
>
>> if that's the case it reads ok...
>>
>>
>> On Fri, Sep 18, 2015 at 4:55 PM, Alexander Bluhm
>> <alexander.bl...@gmx.net> wrote:
>> > Hi,
>> >
>> > I discovered what caused the strange event loss in syslogd during
>> > the hackaton.  I had mixed EV_READ and EV_WRITE events on the ev_read
>> > and ev_write event structures.  The correct way is to use each event
>> > for its read and write purpose and instead switch the handler.  Then
>> > libevent is no longer confused.
>> >
>> > ok?
>> >
>> > bluhm
>> >
>> > Index: usr.sbin/syslogd/evbuffer_tls.c
>> > ===================================================================
>> > RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/evbuffer_tls.c,v
>> > retrieving revision 1.7
>> > diff -u -p -r1.7 evbuffer_tls.c
>> > --- usr.sbin/syslogd/evbuffer_tls.c     10 Sep 2015 18:32:06 -0000      1.7
>> > +++ usr.sbin/syslogd/evbuffer_tls.c     18 Sep 2015 22:53:53 -0000
>> > @@ -44,6 +44,9 @@
>> >  /* prototypes */
>> >
>> >  void bufferevent_read_pressure_cb(struct evbuffer *, size_t, size_t, void 
>> > *);
>> > +static void buffertls_readcb(int, short, void *);
>> > +static void buffertls_writecb(int, short, void *);
>> > +static void buffertls_handshakecb(int, short, void *);
>> >  int evtls_read(struct evbuffer *, int, int, struct tls *);
>> >  int evtls_write(struct evbuffer *, int, struct tls *);
>> >
>> > @@ -96,29 +99,30 @@ buffertls_readcb(int fd, short event, vo
>> >         res = evtls_read(bufev->input, fd, howmuch, ctx);
>> >         switch (res) {
>> >         case TLS_WANT_POLLIN:
>> > -               event_set(&bufev->ev_read, fd, EV_READ, buffertls_readcb,
>> > -                   buftls);
>> > -               goto reschedule;
>> > +               bufferevent_add(&bufev->ev_read, bufev->timeout_read);
>> > +               return;
>> >         case TLS_WANT_POLLOUT:
>> > -               event_set(&bufev->ev_read, fd, EV_WRITE, buffertls_readcb,
>> > +               event_del(&bufev->ev_write);
>> > +               event_set(&bufev->ev_write, fd, EV_WRITE, buffertls_readcb,
>> >                     buftls);
>> > -               goto reschedule;
>> > +               bufferevent_add(&bufev->ev_write, bufev->timeout_write);
>> > +               return;
>> >         case -1:
>> > -               if (errno == EAGAIN || errno == EINTR)
>> > -                       goto reschedule;
>> > -               /* error case */
>> >                 what |= EVBUFFER_ERROR;
>> >                 break;
>> >         case 0:
>> > -               /* eof case */
>> >                 what |= EVBUFFER_EOF;
>> >                 break;
>> >         }
>> >         if (res <= 0)
>> >                 goto error;
>> >
>> > -       event_set(&bufev->ev_read, fd, EV_READ, buffertls_readcb, buftls);
>> > -       bufferevent_add(&bufev->ev_read, bufev->timeout_read);
>> > +       event_del(&bufev->ev_write);
>> > +       event_set(&bufev->ev_write, fd, EV_WRITE, buffertls_writecb, 
>> > buftls);
>> > +       if (bufev->enabled & EV_READ)
>> > +               bufferevent_add(&bufev->ev_read, bufev->timeout_read);
>> > +       if (EVBUFFER_LENGTH(bufev->output) != 0 && bufev->enabled & 
>> > EV_WRITE)
>> > +               bufferevent_add(&bufev->ev_write, bufev->timeout_write);
>> >
>> >         /* See if this callbacks meets the water marks */
>> >         len = EVBUFFER_LENGTH(bufev->input);
>> > @@ -137,10 +141,6 @@ buffertls_readcb(int fd, short event, vo
>> >                 (*bufev->readcb)(bufev, bufev->cbarg);
>> >         return;
>> >
>> > - reschedule:
>> > -       bufferevent_add(&bufev->ev_read, bufev->timeout_read);
>> > -       return;
>> > -
>> >   error:
>> >         (*bufev->errorcb)(bufev, what, bufev->cbarg);
>> >  }
>> > @@ -163,22 +163,18 @@ buffertls_writecb(int fd, short event, v
>> >                 res = evtls_write(bufev->output, fd, ctx);
>> >                 switch (res) {
>> >                 case TLS_WANT_POLLIN:
>> > -                       event_set(&bufev->ev_write, fd, EV_READ,
>> > +                       event_del(&bufev->ev_read);
>> > +                       event_set(&bufev->ev_read, fd, EV_READ,
>> >                             buffertls_writecb, buftls);
>> > -                       goto reschedule;
>> > +                       bufferevent_add(&bufev->ev_read, 
>> > bufev->timeout_read);
>> > +                       return;
>> >                 case TLS_WANT_POLLOUT:
>> > -                       event_set(&bufev->ev_write, fd, EV_WRITE,
>> > -                           buffertls_writecb, buftls);
>> > -                       goto reschedule;
>> > +                       bufferevent_add(&bufev->ev_write, 
>> > bufev->timeout_write);
>> > +                       return;
>> >                 case -1:
>> > -                       if (errno == EAGAIN || errno == EINTR ||
>> > -                           errno == EINPROGRESS)
>> > -                               goto reschedule;
>> > -                       /* error case */
>> >                         what |= EVBUFFER_ERROR;
>> >                         break;
>> >                 case 0:
>> > -                       /* eof case */
>> >                         what |= EVBUFFER_EOF;
>> >                         break;
>> >                 }
>> > @@ -186,8 +182,11 @@ buffertls_writecb(int fd, short event, v
>> >                         goto error;
>> >         }
>> >
>> > -       event_set(&bufev->ev_write, fd, EV_WRITE, buffertls_writecb, 
>> > buftls);
>> > -       if (EVBUFFER_LENGTH(bufev->output) != 0)
>> > +       event_del(&bufev->ev_read);
>> > +       event_set(&bufev->ev_read, fd, EV_READ, buffertls_readcb, buftls);
>> > +       if (bufev->enabled & EV_READ)
>> > +               bufferevent_add(&bufev->ev_read, bufev->timeout_read);
>> > +       if (EVBUFFER_LENGTH(bufev->output) != 0 && bufev->enabled & 
>> > EV_WRITE)
>> >                 bufferevent_add(&bufev->ev_write, bufev->timeout_write);
>> >
>> >         /*
>> > @@ -200,11 +199,6 @@ buffertls_writecb(int fd, short event, v
>> >
>> >         return;
>> >
>> > - reschedule:
>> > -       if (EVBUFFER_LENGTH(bufev->output) != 0)
>> > -               bufferevent_add(&bufev->ev_write, bufev->timeout_write);
>> > -       return;
>> > -
>> >   error:
>> >         (*bufev->errorcb)(bufev, what, bufev->cbarg);
>> >  }
>> > @@ -226,41 +220,30 @@ buffertls_handshakecb(int fd, short even
>> >         res = tls_handshake(ctx);
>> >         switch (res) {
>> >         case TLS_WANT_POLLIN:
>> > -               event_set(&bufev->ev_write, fd, EV_READ,
>> > -                   buffertls_handshakecb, buftls);
>> > -               goto reschedule;
>> > +               bufferevent_add(&bufev->ev_read, bufev->timeout_read);
>> > +               return;
>> >         case TLS_WANT_POLLOUT:
>> > -               event_set(&bufev->ev_write, fd, EV_WRITE,
>> > -                   buffertls_handshakecb, buftls);
>> > -               goto reschedule;
>> > +               bufferevent_add(&bufev->ev_write, bufev->timeout_write);
>> > +               return;
>> >         case -1:
>> > -               if (errno == EAGAIN || errno == EINTR ||
>> > -                   errno == EINPROGRESS)
>> > -                       goto reschedule;
>> > -               /* error case */
>> >                 what |= EVBUFFER_ERROR;
>> >                 break;
>> >         }
>> >         if (res < 0)
>> >                 goto error;
>> >
>> > -       /*
>> > -        * There might be data available in the tls layer.  Try
>> > -        * an read operation and setup the callbacks.  Call the read
>> > -        * callback after enabling the write callback to give the
>> > -        * read error handler a chance to disable the write event.
>> > -        */
>> > +       /* Handshake was successful, change to read and write callback. */
>> > +       event_del(&bufev->ev_read);
>> > +       event_del(&bufev->ev_write);
>> > +       event_set(&bufev->ev_read, fd, EV_READ, buffertls_readcb, buftls);
>> >         event_set(&bufev->ev_write, fd, EV_WRITE, buffertls_writecb, 
>> > buftls);
>> > -       if (EVBUFFER_LENGTH(bufev->output) != 0)
>> > +       if (bufev->enabled & EV_READ)
>> > +               bufferevent_add(&bufev->ev_read, bufev->timeout_read);
>> > +       if (EVBUFFER_LENGTH(bufev->output) != 0 && bufev->enabled & 
>> > EV_WRITE)
>> >                 bufferevent_add(&bufev->ev_write, bufev->timeout_write);
>> > -       buffertls_readcb(fd, 0, buftls);
>> >
>> >         return;
>> >
>> > - reschedule:
>> > -       bufferevent_add(&bufev->ev_write, bufev->timeout_write);
>> > -       return;
>> > -
>> >   error:
>> >         (*bufev->errorcb)(bufev, what, bufev->cbarg);
>> >  }
>> > @@ -283,7 +266,7 @@ buffertls_connect(struct buffertls *buft
>> >
>> >         event_del(&bufev->ev_read);
>> >         event_del(&bufev->ev_write);
>> > -
>> > +       event_set(&bufev->ev_read, fd, EV_READ, buffertls_handshakecb, 
>> > buftls);
>> >         event_set(&bufev->ev_write, fd, EV_WRITE, buffertls_handshakecb,
>> >             buftls);
>> >         bufferevent_add(&bufev->ev_write, bufev->timeout_write);
>> >

Reply via email to