Esempio n. 1
0
int BufferManager::write(TCPSocket &sock)
{
    const unsigned int reqlen = (unsigned int)m_lIovList.size();
    struct iovec outdata[reqlen];
    
    memset(outdata,0,reqlen * sizeof(struct iovec));
    
    std::list<iov_req>::iterator aIt,pIt;
    aIt = m_lIovList.begin();
    unsigned int num = 0;
    
    while( aIt != m_lIovList.end())
    {
        outdata[num].iov_base = aIt->m_Iov.iov_base;
        outdata[num].iov_len = aIt->m_Iov.iov_len;
        ++num;
        ++aIt;
    }
    
    int ret = -1;
    while((ret = sock.writevSocket(outdata,reqlen)) < 0)
    {
        if(errno == EINTR)
            continue;
        if( (errno != EWOULDBLOCK) || (errno != EAGAIN))
        {
            handleWriteError();
            return FAILED;
        }
    }
    
    int download = ret;
    #ifdef DEBUG
    std::cout << "send data length:"<< ret << std::endl;
    #endif
    aIt = m_lIovList.begin();
    while(ret > 0 && aIt != m_lIovList.end())
    {
        pIt = aIt++;
        if((unsigned int) ret >= pIt->m_Iov.iov_len)
        {
            ret -= pIt->m_Iov.iov_len;
            if(pIt->m_bComplete)
            {
                if(pIt->m_Iov.iov_base)
                {
                    delete [](char *)(pIt->m_Iov.iov_base);
                    pIt->m_Iov.iov_base = NULL;
                }
            } else {
                if(m_pLastIov)
                {
                    delete [](char *)m_pLastIov;
                    m_pLastIov = NULL;
                }
            } 
            
            if(pIt->m_pTask)
            {
                pIt->m_pTask->writeBack(true);
            } else 
            {
                if(m_pAgent)
                {
                    m_pAgent->writeBack(true);
                } else {
                    handleError("the BufferManager don't relate with a Agent");
                    return FAILED;
                }
            }
            m_lIovList.erase(pIt);
        } else 
        {
            if(pIt->m_bComplete)
            {
                m_pLastIov = pIt->m_Iov.iov_base;
                pIt->m_bComplete = false;
            }
            pIt->m_Iov.iov_base = (void *)(((char *)pIt->m_Iov.iov_base + ret));
            pIt->m_Iov.iov_len -= (unsigned int)ret;
            break;
        }
    }
    
    return download;
}
Esempio n. 2
0
int BufferManager::write(TCPSocket &sock)
{
    unsigned int reqlen = (unsigned int)mIovList.size();

    if (reqlen > m_IovLimit) {
        reqlen = m_IovLimit;
    }

    struct iovec outdata[ reqlen ];

    memset(outdata, 0, reqlen * sizeof(struct iovec));

    list<iov_req>::iterator aIt , pIt;

    aIt = mIovList.begin();

    unsigned int num = 0;

    while (aIt != mIovList.end() && num < m_IovLimit) {
        outdata[num].iov_base = (*aIt).mIov.iov_base;
        outdata[num].iov_len = (*aIt).mIov.iov_len;
        ++num;
        ++aIt;
    }

    int ret = -1;

    while ((ret = sock.writevSocket(outdata, reqlen)) < 0) {
        if (errno == EINTR) {
            continue;
        }

        if (errno != EWOULDBLOCK) {
            handleWriteError();
            return FAILED;
        }
    }

    int download = ret;
    aIt = mIovList.begin();

    while (ret > 0 && aIt != mIovList.end()) {
        pIt = aIt++;

        if ((unsigned int)ret >= (*pIt).mIov.iov_len) {
            ret -= (*pIt).mIov.iov_len;

            if ((*pIt).mComplete) {
                if ((*pIt).mIov.iov_base) {
                    delete [](char *)(*pIt).mIov.iov_base;
                    (*pIt).mIov.iov_base = NULL;
                }

            } else {
                if (mLastIov != NULL) {
                    delete [](char *)mLastIov;
                    mLastIov = NULL;
                }
            }

            if ((*pIt).mTask != NULL) {
                (*pIt).mTask->writeBack(true);

            } else {
                if (m_Agent != NULL) {
                    m_Agent->writeBack(true);

                } else {
                    DEV_LOG(LERROR, OUT_BOTH, "the BufferManager don't relate a Agent");
                    return FAILED;
                }
            }

            mIovList.erase(pIt);

        } else {
            if ((*pIt).mComplete) {
                mLastIov = (*pIt).mIov.iov_base;
                (*pIt).mComplete = false;
            }

            (*pIt).mIov.iov_base = (void *)((char *)((*pIt).mIov.iov_base) + ret);
            (*pIt).mIov.iov_len -= (unsigned int)ret;
            break;
        }
    }

    return download;
}