Ошибка aio_write при сборке релиза - PullRequest
0 голосов
/ 07 апреля 2011

Я использую aio_write, он работает в отладочной сборке, но не в выпуске.Я проверил конструктор, что все инициализировано, и я не получаю никаких предупреждений о неинициализированных переменных.Класс собирает данные, которые должны быть записаны на диск, по 16 тыс. Блоков.Если размер данных меньше 16 КБ, он работает даже в сборках выпуска.Если данные больше 16K, записывается только первый блок.WriteBuffer :: ContinueWriteToFile возвращает WriteFileState_Active неограниченно.

WriteBuffer_posix.h:

class WriteBufferPlatformData
{
public:
    WriteBufferPlatformData();
    ~WriteBufferPlatformData();

    aiocb aioData;
    WriteBuffer::BufferVector::iterator currentBuffer;
};

WriteBuffer_posix.cpp:

WriteBufferPlatformData::WriteBufferPlatformData() :
    aioData(),
    currentBuffer()
{
    memset(&aioData,0,sizeof(aioData));
    aioData.aio_fildes=-1;
}

WriteBufferPlatformData::~WriteBufferPlatformData()
{
    if (0<=aioData.aio_fildes) {
        close(aioData.aio_fildes);
    }
}

WriteBuffer::WriteFileState WriteBuffer::StartWriteToFile(const char * filename)
{
    NYMPH_ASSERT(0>m_platformData->aioData.aio_fildes);

    m_platformData->aioData.aio_fildes=open(filename,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);

    NYMPH_ASSERT2(0<=m_platformData->aioData.aio_fildes,"Could not open file for writing: %s (%d)",filename,errno);
    if (0>m_platformData->aioData.aio_fildes) {
        return WriteFileState_Failed;
    }

    if (m_buffers.empty()) {
        close(m_platformData->aioData.aio_fildes);
        m_platformData->aioData.aio_fildes=-1;
        return WriteFileState_Complete;
    }

    m_isWriting=true;
    m_platformData->currentBuffer=m_buffers.begin();
    return ContinueWriteToFile();
}

WriteBuffer::WriteFileState WriteBuffer::ContinueWriteToFile()
{
    NYMPH_ASSERT(0<=m_platformData->aioData.aio_fildes);

    if (0!=m_platformData->aioData.aio_nbytes) {
        int writeErrno=aio_error(&(m_platformData->aioData));
        if (EINPROGRESS==writeErrno) {
            return WriteFileState_Active;
        }

        NYMPH_ASSERT(aio_return(&(m_platformData->aioData))==m_platformData->aioData.aio_nbytes);
        m_platformData->aioData.aio_nbytes=0;
        ++(m_platformData->currentBuffer);

        if (m_buffers.end()==m_platformData->currentBuffer) {
            close(m_platformData->aioData.aio_fildes);
            m_platformData->aioData.aio_fildes=-1;
            return WriteFileState_Complete;
        }
    }

    if (0==m_platformData->aioData.aio_nbytes) {
        m_platformData->aioData.aio_buf=*(m_platformData->currentBuffer);
        if (m_buffers.back()==m_platformData->aioData.aio_buf) {
            m_platformData->aioData.aio_nbytes=m_offset;
        } else {
            m_platformData->aioData.aio_nbytes=kBufferSize;
        }
        m_platformData->aioData.aio_offset=lseek(m_platformData->aioData.aio_fildes,0,SEEK_END);

        if (0!=aio_write(&(m_platformData->aioData))) {
            m_platformData->aioData.aio_nbytes=0;
            NYMPH_ASSERT(EAGAIN==errno);
            if (EAGAIN!=errno) {
                close(m_platformData->aioData.aio_fildes);
                m_platformData->aioData.aio_fildes=-1;
                return WriteFileState_Failed;
            }
        }
    }

    return WriteFileState_Active;
}

1 Ответ

0 голосов
/ 07 апреля 2011

Несмотря на то, что я прочитал на странице руководства, кажется, что вызов aio_return необходим, и изменение NYMPH_ASSERT (aio_return ... на NYMPH_VERIFY (aio_return ...) исправило проблему.

...