static int proxy_wstunnel_pump(ws_baton_t *baton, apr_time_t timeout, int try_async) {
    request_rec *r = baton->r;
    conn_rec *c = r->connection;
    proxy_conn_rec *conn = baton->proxy_connrec;
    apr_socket_t *sock = conn->sock;
    conn_rec *backconn = conn->connection;
    const apr_pollfd_t *signalled;
    apr_int32_t pollcnt, pi;
    apr_int16_t pollevent;
    apr_pollset_t *pollset = baton->pollset;
    apr_socket_t *client_socket = baton->client_soc;
    apr_status_t rv;
    apr_bucket_brigade *bb = baton->bb;

    while(1) { 
        if ((rv = apr_pollset_poll(pollset, timeout, &pollcnt, &signalled))
                != APR_SUCCESS) {
            if (APR_STATUS_IS_EINTR(rv)) {
                continue;
            }
            else if (APR_STATUS_IS_TIMEUP(rv)) { 
                if (try_async) { 
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(02542) "Attempting to go async");
                    return SUSPENDED;
                }
                else { 
                    return HTTP_REQUEST_TIME_OUT;
                }
            }
            else { 
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02444) "error apr_poll()");
                return HTTP_INTERNAL_SERVER_ERROR;
            }
        }

        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(02445)
                "woke from poll(), i=%d", pollcnt);

        for (pi = 0; pi < pollcnt; pi++) {
            const apr_pollfd_t *cur = &signalled[pi];

            if (cur->desc.s == sock) {
                pollevent = cur->rtnevents;
                if (pollevent & (APR_POLLIN | APR_POLLHUP)) {
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(02446)
                            "sock was readable");
                    rv = proxy_wstunnel_transfer(r, backconn, c, bb, "sock");
                }
                else if (pollevent & APR_POLLERR) {
                    rv = APR_EPIPE;
                    ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(02447)
                            "error on backconn");
                }
                else { 
                    rv = APR_EGENERAL;
                    ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(02605)
                            "unknown event on backconn %d", pollevent);
                }
            }
            else if (cur->desc.s == client_socket) {
                pollevent = cur->rtnevents;
                if (pollevent & (APR_POLLIN | APR_POLLHUP)) {
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(02448)
                            "client was readable");
                    rv = proxy_wstunnel_transfer(r, c, backconn, bb, "client");
                }
                else if (pollevent & APR_POLLERR) {
                    rv = APR_EPIPE;
                    c->aborted = 1;
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(02607)
                            "error on client conn");
                }
                else { 
                    rv = APR_EGENERAL;
                    ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(02606)
                            "unknown event on client conn %d", pollevent);
                }
            }
            else {
                rv = APR_EBADF;
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02449)
                        "unknown socket in pollset");
            }

        }
        if (rv != APR_SUCCESS) {
            break;
        }

    }
    ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
            "finished with poll() - cleaning up");

    return OK;
}