static
globus_result_t
globus_l_xio_win32_socket_register_write(
    globus_l_xio_win32_socket_t *       handle,
    globus_i_xio_system_op_info_t *     write_info)
{
    globus_result_t                     result;
    GlobusXIOName(globus_l_xio_win32_socket_register_write);
    
    GlobusXIOSystemDebugEnterFD(handle->socket);
    
    /* I have to do this outside the lock because of lock inversion issues */
    if(write_info->op && globus_xio_operation_enable_cancel(
        write_info->op, globus_l_xio_win32_socket_cancel_cb, write_info))
    {
        result = GlobusXIOErrorCanceled();
        goto error_cancel_enable;
    }

    win32_mutex_lock(&handle->lock);
    {
        if(write_info->state == GLOBUS_I_XIO_SYSTEM_OP_CANCELED)
        {
            result = globus_error_put(write_info->error);
            goto error_canceled;
        }

        if(handle->write_info)
        {
            result = GlobusXIOErrorAlreadyRegistered();
            goto error_already_registered;
        }
        
        write_info->state = GLOBUS_I_XIO_SYSTEM_OP_PENDING;
        /* if select() functionality requested, only handle after we receive
         * write event
         * 
         * also dont call for connect operations.  waitforbytes == 0 in this
         * case and handle->ready_events should not yet have a write event
         */
        if(write_info->waitforbytes > 0 || handle->ready_events & FD_WRITE)
        {
            globus_l_xio_win32_socket_handle_write(handle, write_info);
        }
        
        if(write_info->state != GLOBUS_I_XIO_SYSTEM_OP_COMPLETE)
        {
            /* make sure we're set up to be notified of events */
            long needevents;
            
            if(write_info->type == GLOBUS_I_XIO_SYSTEM_OP_CONNECT)
            {
                needevents = FD_CONNECT|FD_CLOSE;
            }
            else
            {
                needevents = FD_WRITE|FD_CLOSE;
            }
            
            if((handle->eventselect & needevents) != needevents)
            {
                if(WSAEventSelect(
                    handle->socket, handle->event,
                    handle->eventselect|needevents) == SOCKET_ERROR)
                {
                    write_info->error = GlobusXIOErrorObjSystemError(
                        "WSAEventSelect", WSAGetLastError());
                }
                else
                {
                    handle->eventselect |= needevents;
                }
            }
            
            if(!write_info->error)
            {
                handle->write_info = write_info;
                write_info = 0;
            }
        }
    }
    win32_mutex_unlock(&handle->lock);
    
    /* do this outside the lock to avoid unnecessary contention */
    if(write_info)
    {
        globus_l_xio_win32_socket_complete(write_info, GLOBUS_FALSE);
    }

    GlobusXIOSystemDebugExitFD(handle->socket);
    return GLOBUS_SUCCESS;

error_already_registered:
error_canceled:
    write_info->state = GLOBUS_I_XIO_SYSTEM_OP_COMPLETE;
    win32_mutex_unlock(&handle->lock);
    if(write_info->op)
    {
        globus_xio_operation_disable_cancel(write_info->op);
    }
error_cancel_enable:
    GlobusXIOSystemDebugExitWithErrorFD(handle->socket);
    return result;
}
/**
 * Called with mutex locked
 */
globus_result_t
globus_i_xio_http_set_end_of_entity(
    globus_i_xio_http_handle_t *        http_handle)
{
    globus_result_t                     result = GLOBUS_SUCCESS;
    globus_i_xio_http_header_info_t *   headers;
    static globus_xio_iovec_t           end_of_body_iovec = { "0\r\n\r\n", 5 };
    GlobusXIOName(globus_i_xio_http_set_end_of_entity);

    if (http_handle->write_operation.operation != NULL)
    {
        result = GlobusXIOErrorAlreadyRegistered();

        goto error_exit;
    }
    else if (http_handle->target_info.is_client)
    {
        headers = &http_handle->request_info.headers;
    }
    else
    {
        headers = &http_handle->response_info.headers;
    }
    
    if (http_handle->send_state == GLOBUS_XIO_HTTP_STATUS_LINE)
    {
        /* To send an empty response from server */
        result = globus_i_xio_http_server_write_response(
                http_handle,
                NULL,
                0,
                NULL);
    }
    else if (http_handle->send_state == GLOBUS_XIO_HTTP_CHUNK_BODY)
    {
        result = globus_xio_driver_operation_create(
                &http_handle->write_operation.operation,
                http_handle->handle);

        if (result != GLOBUS_SUCCESS)
        {
            goto error_exit;
        }

        result = globus_xio_driver_pass_write(
                http_handle->write_operation.operation,
                &end_of_body_iovec,
                1,
                5,
                globus_l_xio_http_write_eof_callback,
                http_handle);

        if (result != GLOBUS_SUCCESS)
        {
            globus_xio_driver_operation_destroy(
                    http_handle->write_operation.operation);
        }
        else
        {
            http_handle->send_state = GLOBUS_XIO_HTTP_EOF;
        }
    }
error_exit:
    return result;
}