[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[Libevent-users] Re: [HELP] How to safely free a defer callback bufferevent in readcb



I am trying to fix this problem but failed.

here is some more information:
1) this issue only happens while both defer callback and
bufferevent_openssl are used, otherwise, there is no such warning.
2) although most of the time, the warning is invoked,  but there is a
few time that the warning does not appear.
3) I add some debug code into epoll.c, function epoll_apply_changes()
(line 220 - 228)
    217     memset(&epev, 0, sizeof(epev));
    218     epev.data.fd = ch->fd;
    219     epev.events = events;
    220     printf("%s:%d %d\n", __FILE__, __LINE__, ch->fd);
    221     printf("Epoll %s on fd %d.  Old events were %d; read
change was %d; write change was %d.\n",
    222             op == EPOLL_CTL_ADD?"ADD":
    223             op == EPOLL_CTL_DEL?"DEL":
    224             op == EPOLL_CTL_MOD?"MOD":"???",
    225             ch->fd,
    226             ch->old_events,
    227             ch->read_change, ch->write_change
    228             );
    229     if (epoll_ctl(epollop->epfd, op, ch->fd, &epev) == -1) {

I found some strange libevent behavior, here is log printed on the
console, fd=10 is the socket connected to the client, fd=11 is the
socket connected to back server.

----begin (no warning)----
01 accepted connection from 192.168.161.1:3692 on 192.168.161.161:446.
02 Epoll ADD on fd 10.  Old events were 0; read change was 1; write
change was 1.
03 Epoll ADD on fd 11.  Old events were 0; read change was 1; write
change was 1.
04 Epoll MOD on fd 11.  Old events were 6; read change was 0; write
change was 2.
05 Epoll MOD on fd 10.  Old events were 6; read change was 0; write
change was 2.
06 Epoll MOD on fd 10.  Old events were 2; read change was 1; write
change was 1.
07 Epoll MOD on fd 10.  Old events were 6; read change was 0; write
change was 2.
08 write deny response 403
09 Epoll DEL on fd 10.  Old events were 2; read change was 2; write
change was 0.
10 Epoll DEL on fd 11.  Old events were 2; read change was 2; write
change was 0.
----end----

----begin (warning) ----
01 accepted connection from 192.168.161.1:3692 on 192.168.161.161:446.
02 Epoll ADD on fd 10.  Old events were 0; read change was 1; write
change was 1.
03 Epoll ADD on fd 11.  Old events were 0; read change was 1; write
change was 1.
04 Epoll MOD on fd 11.  Old events were 6; read change was 0; write
change was 2.
05 Epoll MOD on fd 10.  Old events were 6; read change was 0; write
change was 2.
06 Epoll MOD on fd 10.  Old events were 2; read change was 1; write
change was 1.
07 write deny response 403
08 Epoll DEL on fd 10.  Old events were 2; read change was 2; write
change was 0.
09 [warn] Epoll MOD on fd 10 failed.  Old events were 6; read change
was 2; write change was 0.: Bad file descriptor
10 Epoll DEL on fd 11.  Old events were 2; read change was 2; write
change was 0.
----end----

the differences are at line number 07 and 09. I am all rather confused.

I'm using openssl 0.9.8n, libevent 2.0.5-beta

Any advice will be appreciated. Thanks very much.


On Mon, May 31, 2010 at 4:48 PM, Zhuang Yuyao <mlistz@xxxxxxxxx> wrote:
> Hi,
>
> I am working on a http proxy program based on le-proxy. the proxy has
> a feature to block requests to some special urls, then return to the
> client a 403 forbidden or 302 redirect response.
>
> I tried to do it in bufferevent readcb, here are the code sample i wrote:
>
> static void
> readcb(struct bufferevent *bev, void *ctx)
> {
>  struct bufferevent *partner = (struct bufferevent *)ctx;
>
>  int r = session_handle(bev, partner);
>  if (r == 1) { //the url need to be blocked and the output evbuffer
> of bev has been set to "HTTP/1.0 403\r\n\r\n"
>    bufferevent_disable(bev, EV_READ);
>    struct evbuffer *b = bufferevent_get_input(bev);
>    evbuffer_drain(b, evbuffer_get_length(b));
>
>    if (partner) {
>      bufferevent_disable(partner, EV_READ|EV_WRITE);
>      bufferevent_free(partner);
>    }
>    if (evbuffer_get_length(bufferevent_get_output(bev))) {
>      bufferevent_setcb(bev, NULL, close_on_finished_writecb, eventcb, NULL);
>    }
>    else {
>      bufferevent_free(bev);
>    }
>  }
>  //otherwise
>  .....
> }
>
> with defer callback, when the above code is called, (ie. a request to
> the to-be-blocked url is found)
> I got the following warnings:
> [warn] Epoll MOD on fd 10 failed.  Old events were 6; read change was
> 2; write change was 0.: Bad file descriptor
>
> The warning does not appear if the BEV_OPT_DEFER_CALLBACKS is not set.
>
> Can anyone please explain where this warning comes from, and how to
> avoid such a warning?
>
>
> Thanks very much.
>
> Best regards,
>  Zhuang
>
***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users    in the body.