예제 #1
0
/*
 *  Outgoing data service routine. May be called multiple times.
 */
static void sendOutgoingService(MaQueue *q)
{
    MaConn      *conn;
    MaResponse  *resp;
    int         written;
    int         errCode;

    conn = q->conn;
    resp = conn->response;

    if (conn->sock == 0) {
        return;
    }

    /*
     *  Loop doing non-blocking I/O until blocked or all the packets received are written.
     */
    while (1) {
        /*
         *  Rebuild the iovector only when the past vector has been completely written. Simplifies the logic quite a bit.
         */
        written = 0;
        if (q->ioIndex == 0 && buildSendVec(q) <= 0) {
            break;
        }
        /*
         *  Write the vector and file data. Exclude the file entry in the io vector.
         */
        written = (int) mprSendFileToSocket(conn->sock, resp->file, q->ioPos, q->ioCount, q->iovec, q->ioIndex, NULL, 0);
        mprLog(q, 5, "Send connector written %d", written);
        if (written < 0) {
            errCode = mprGetError();
            if (errCode == EAGAIN || errCode == EWOULDBLOCK) {
                maRequestWriteBlocked(conn);
                break;
            }
            if (errCode == EPIPE || errCode == ECONNRESET) {
                maDisconnectConn(conn);
            } else {
                mprLog(conn, 7, "mprSendFileToSocket failed, errCode %d", errCode);
                maDisconnectConn(conn);
            }
            freeSentPackets(q, MAXINT);
            break;

        } else if (written == 0) {
            /* Socket is full. Wait for an I/O event */
            maRequestWriteBlocked(conn);
            break;

        } else if (written > 0) {
            resp->bytesWritten += written;
            freeSentPackets(q, written);
            adjustSendVec(q, written);
        }
    }
    if (q->ioCount == 0 && q->flags & MA_QUEUE_EOF) {
        maCompleteRequest(conn);
    }
}
예제 #2
0
static void netOutgoingService(MaQueue *q)
{
    MaConn      *conn;
    MaResponse  *resp;
    int         written, errCode;

    conn = q->conn;
    resp = conn->response;
    
    while (q->first || q->ioIndex) {
        written = 0;
        if (q->ioIndex == 0 && buildNetVec(q) <= 0) {
            break;
        }
        /*
         *  Issue a single I/O request to write all the blocks in the I/O vector
         */
        errCode = mprGetOsError();
        mprAssert(q->ioIndex > 0);
        written = mprWriteSocketVector(conn->sock, q->iovec, q->ioIndex);
        mprLog(q, 5, "Net connector written %d", written);
        if (written < 0) {
            errCode = mprGetOsError();
            if (errCode == EAGAIN || errCode == EWOULDBLOCK) {
                maRequestWriteBlocked(conn);
                break;
            }
            if (errCode == EPIPE || errCode == ECONNRESET) {
                maDisconnectConn(conn);
            } else {
                mprLog(conn, 7, "mprVectorWriteSocket failed, error %d", errCode);
                maDisconnectConn(conn);
            }
            freeNetPackets(q, MAXINT);
            break;

        } else if (written == 0) {
            /* 
             * Socket full. Wait for an I/O event. Conn.c will setup listening for write events if the queue is non-empty
             */
            maRequestWriteBlocked(conn);
            break;

        } else if (written > 0) {
            resp->bytesWritten += written;
            freeNetPackets(q, written);
            adjustNetVec(q, written);
        }
    }
    if (q->ioCount == 0 && q->flags & MA_QUEUE_EOF) {
        maCompleteRequest(conn);
    }
}
예제 #3
0
파일: request.c 프로젝트: gamman/appweb-3
void maAbortConnection(MaConn *conn, int code, cchar *fmt, ...)
{
    va_list     args;

    mprAssert(fmt);

    mprLog(conn, 4, "Abort conn fd %d", conn->sock ? conn->sock->fd : 0);
    if (!conn->requestFailed) {
        va_start(args, fmt);
        reportFailure(conn, code, fmt, args);
        va_end(args);
        maDisconnectConn(conn);
    }
}