
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_event.h>


ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in)
{
    int               rc;
    char             *prev;
    size_t            size, sent;
    LPWSABUF          wsabuf;
    ngx_err_t         err;
    ngx_event_t      *wev;
    ngx_array_t       wsabufs;
    ngx_chain_t      *ce;
    LPWSAOVERLAPPED   ovlp;

#if 0

iocp:
    if ready
       get result
       update chain
       return if done;
    wsasend

non-block
    for ( ;; ) {
       wsasend
       if no again
          update chain
          return if done;
    }


    for ( ;; ) {

        make buffers and limit data for both ovlp and nonblocked,
                     configured in events module

        if (iocp && ready) {
            get result

        } else {
            if (file)
                transmitfile
            else
                wsasend

            if (iocp)
                return chain
            return chain if again
            here is result
        }

        if (result)
            update chain;
            return chain if done
        }
    }


#endif

    wev = c->write;

    if (((ngx_event_flags & NGX_USE_AIO_EVENT) && !wev->ready)
        || ((ngx_event_flags & NGX_USE_AIO_EVENT) == 0))
    {
        /*
         * WSABUFs must be 4-byte aligned otherwise
         * WSASend() will return undocumented WSAEINVAL error.
         */

        ngx_init_array(wsabufs, c->pool, 10, sizeof(WSABUF), NGX_CHAIN_ERROR);

        prev = NULL;
        wsabuf = NULL;

        /* create the WSABUF and coalesce the neighbouring chain entries */
        for (ce = in; ce; ce = ce->next) {

            if (prev == ce->hunk->pos) {
                wsabuf->len += ce->hunk->last - ce->hunk->pos;
                prev = ce->hunk->last;

            } else {
                ngx_test_null(wsabuf, ngx_push_array(&wsabufs),
                              NGX_CHAIN_ERROR);
                wsabuf->buf = ce->hunk->pos;
                wsabuf->len = ce->hunk->last - ce->hunk->pos;
                prev = ce->hunk->last;
            }
        }

        if (ngx_event_flags & NGX_USE_AIO_EVENT) {
            ovlp = (LPWSAOVERLAPPED) &c->write->ovlp;
            ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));

        } else {
            ovlp = NULL;
        }

        rc = WSASend(c->fd, wsabufs.elts, wsabufs.nelts, &sent, 0, ovlp, NULL);

        if (rc == -1) {
            err = ngx_errno;
            if (err == WSA_IO_PENDING) {
                sent = 0;

            } else if (err == WSAEWOULDBLOCK) {
                sent = 0;
                ngx_log_error(NGX_LOG_INFO, c->log, err, "WSASend() EAGAIN");

            } else {
                ngx_log_error(NGX_LOG_CRIT, c->log, err, "WSASend() failed");
                return NGX_CHAIN_ERROR;
            }

        } else {

            if (ngx_event_flags & NGX_USE_IOCP_EVENT) {

                /*
                 * If a socket was bound with I/O completion port then
                 * GetQueuedCompletionStatus() would anyway return its status
                 * despite that WSASend() was already completed.
                 */

                sent = 0;
            }
        }

    } else {
        if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
            wev->ready = 0;

            /* the overlapped WSASend() completed */

            if (wev->ovlp.error) {
                ngx_log_error(NGX_LOG_ERR, c->log, wev->ovlp.error,
                              "WSASend() failed");
                return NGX_CHAIN_ERROR;
            }

            sent = wev->available;
        }
    }

#if (NGX_DEBUG_WRITE_CHAIN)
    ngx_log_debug(c->log, "WSASend(): %d" _ sent);
#endif

    c->sent += sent;

    for (ce = in; ce && sent > 0; ce = ce->next) {

        size = ce->hunk->last - ce->hunk->pos;

        if (sent >= size) {
            sent -= size;

            if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
                ce->hunk->pos = ce->hunk->last;
            }

            continue;
        }

        if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
            ce->hunk->pos += sent;
        }

        break;
    }

    ngx_destroy_array(&wsabufs);

    return ce;
}
