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; }