On Friday, June 01, 2012 05:55:37 PM Justin Karneges wrote:
> I've discovered that if I start mongrel2 and connect to the https port and
> close the connection without performing an ssl handshake, then mongrel2
> goes to 100% cpu. It stays this way about 2 minutes even though there are
> no connections and no further requests. I can reproduce this every time.
> It is the act of closing that trips it out. If I sit there with the
> connection open and do nothing, then all is well.
> 
> I do not get this problem if I connect+close on a non-ssl mongrel2.
> 
> Performing full https requests seem to be fine. Requesting a resource that
> results in a long poll and then closing the connection is also fine.

In io.c there is this method:

static int ssl_fdrecv_wrapper(void *p_iob, unsigned char *ubuffer, int len)
{
    IOBuf *iob = (IOBuf *) p_iob;
    return fdrecv1(iob->fd, (char *) ubuffer, len);
}

It returns the return value of fdrecv1 directly, which matches the recv() 
system call. That is, >0 means data, 0 means EOF, and <0 is error. However, 
when polarssl invokes this method to read data, it makes no distinction about 
EOF, and treats a return value of 0 to mean no data. The rapid cpu usage is 
fdrecv1() constantly returning 0.

I'm not sure of the right way for Mongrel2 to recognize EOF here and clean 
things up, but as a quick hack I changed the above method to return an error 
to polarssl if EOF is encountered:

static int ssl_fdrecv_wrapper(void *p_iob, unsigned char *ubuffer, int len)
{
    IOBuf *iob = (IOBuf *) p_iob;
    int ret = fdrecv1(iob->fd, (char *) ubuffer, len);
    if(ret == 0)
        return -1;
    else
        return ret;
}

Now the cpu issue is gone. Of course, the behavior is wrong, and could cause 
problems where client initiated closes have meaning (uploads?).

Justin

Reply via email to