void TFileAioLogger::log(const QByteArray &msg)
{
    QMutexLocker locker(&d->mutex);

    Q_ASSERT(isOpen());

    // check whether last writing is finished
    if (d->syncBuffer.count() > 0) {
        struct aiocb *lastcb = d->syncBuffer.last();
        if (aio_error(lastcb) != EINPROGRESS) {
            d->clearSyncBuffer();
        }
    }

    struct aiocb *cb = new struct aiocb;
    memset(cb, 0, sizeof(struct aiocb));

    cb->aio_fildes = d->fileDescriptor;
    cb->aio_nbytes = msg.length();
    cb->aio_buf = new char[msg.length()];
    memcpy((void *)cb->aio_buf, msg.data(), msg.length());

    if (tf_aio_write(cb) < 0) {
        tSystemError("log write failed");
        delete[] (char *)cb->aio_buf;
        delete cb;

        close();
        return;
    }
    d->syncBuffer << cb;
}
int TFileAioWriter::write(const char *data, int length)
{
    if (!isOpen()) {
        return -1;
    }

    if (length <= 0) {
        return -1;
    }

    if (d->syncBuffer.count() > 0) {
        if (d->mutex.tryLock()) {
            // check whether head's item  writing is finished
            struct aiocb *headcb;
            while (d->syncBuffer.head(headcb)) {
                if (aio_error(headcb) == EINPROGRESS) {
                    break;
                }

                if (d->syncBuffer.dequeue(headcb)) {
                    delete[] (char *)headcb->aio_buf;
                    delete headcb;
                } else {
                    break;
                }
            }
            d->mutex.unlock();
        }

        if (d->syncBuffer.count() > MAX_NUM_BUFFERING_DATA) {
            flush();
        }
    }

    struct aiocb *cb = new struct aiocb;
    memset(cb, 0, sizeof(struct aiocb));

    cb->aio_fildes = d->fileDescriptor;
    cb->aio_nbytes = length;
    cb->aio_buf = new char[length];
    memcpy((void *)cb->aio_buf, data, length);

    int ret = tf_aio_write(cb);
    int err = errno;

    if (ret < 0) {
        //fprintf(stderr, "aio_write error fd:%d (pid:%d tid:%d) ret:%d errno:%d\n", d->fileDescriptor, getpid(), gettid(), ret, err);
        //fprintf(stderr, "aio_write str: %s\n", data);
        delete (char *)cb->aio_buf;
        delete cb;

        if (err != EAGAIN) {
            close();
        } else {
#ifdef Q_OS_DARWIN
            // try sync-write
            return (tf_write(d->fileDescriptor, data, length) > 0) ? 0 : -1;
#endif
        }
        return ret;
    }

    d->syncBuffer.enqueue(cb);
    return 0;
}