apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *bb)
{
    conn_rec *c = f->c;
    core_net_rec *net = f->ctx;
    apr_socket_t *sock = net->client_socket;
    core_output_filter_ctx_t *ctx = net->out_ctx;
    apr_interval_time_t sock_timeout = 0;
    apr_status_t rv;

    /* Fail quickly if the connection has already been aborted. */
    if (c->aborted) {
        apr_brigade_cleanup(bb);
        return APR_ECONNABORTED;
    }

    if (ctx == NULL) {
        ctx = apr_pcalloc(c->pool, sizeof(*ctx));
        net->out_ctx = (core_output_filter_ctx_t *)ctx;
        /*
         * Need to create tmp brigade with correct lifetime. Passing
         * NULL to apr_brigade_split_ex would result in a brigade
         * allocated from bb->pool which might be wrong.
         */
        ctx->tmp_flush_bb = apr_brigade_create(c->pool, c->bucket_alloc);
    }

    /* remain compatible with legacy MPMs that passed NULL to this filter */
    if (bb == NULL) {
        if (ctx->empty_bb == NULL) {
            ctx->empty_bb = apr_brigade_create(c->pool, c->bucket_alloc);
        }
        bb = ctx->empty_bb;
    }

    /* Prepend buckets set aside, if any. */
    ap_filter_reinstate_brigade(f, bb, NULL);
    if (APR_BRIGADE_EMPTY(bb)) {
        return APR_SUCCESS;
    }

    /* Non-blocking writes on the socket in any case. */
    apr_socket_timeout_get(sock, &sock_timeout);
    apr_socket_timeout_set(sock, 0);

    do {
        rv = send_brigade_nonblocking(sock, bb, ctx, c);
        if (APR_STATUS_IS_EAGAIN(rv)) {
            /* Scan through the brigade and decide whether we must absolutely
             * flush the remaining data, based on ap_filter_reinstate_brigade()
             * rules. If so, wait for writability and retry, otherwise we did
             * our best already and can wait for the next call.
             */
            apr_bucket *flush_upto;
            ap_filter_reinstate_brigade(f, bb, &flush_upto);
            if (flush_upto) {
                apr_int32_t nfd;
                apr_pollfd_t pfd;
                memset(&pfd, 0, sizeof(pfd));
                pfd.reqevents = APR_POLLOUT;
                pfd.desc_type = APR_POLL_SOCKET;
                pfd.desc.s = sock;
                pfd.p = c->pool;
                do {
                    rv = apr_poll(&pfd, 1, &nfd, sock_timeout);
                } while (APR_STATUS_IS_EINTR(rv));
            }
        }
    } while (rv == APR_SUCCESS && !APR_BRIGADE_EMPTY(bb));

    /* Restore original socket timeout before leaving. */
    apr_socket_timeout_set(sock, sock_timeout);

    if (rv != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(rv)) {
        /* The client has aborted the connection */
        ap_log_cerror(
                APLOG_MARK, APLOG_TRACE1, rv, c,
                "core_output_filter: writing data to the network");
        apr_brigade_cleanup(bb);
        c->aborted = 1;
        return rv;
    }

    return ap_filter_setaside_brigade(f, bb);
}