/* * We keep on reading as long as we have something to read, a buffer * to put it in and reading is not stopped by flow control. */ void AsynchIO::readable(DispatchHandle& h) { AbsTime readStartTime = AbsTime::now(); size_t total = 0; int readCalls = 0; do { // (Try to) get a buffer if (!bufferQueue.empty()) { // Read into buffer BufferBase* buff = bufferQueue.front(); assert(buff); bufferQueue.pop_front(); errno = 0; int readCount = buff->byteCount-buff->dataCount; int rc = socket.read(buff->bytes + buff->dataCount, readCount); int64_t duration = Duration(readStartTime, AbsTime::now()); ++readCalls; if (rc > 0) { buff->dataCount += rc; threadReadTotal += rc; total += rc; readCallback(*this, buff); if (rc != readCount) { // If we didn't fill the read buffer then time to stop reading QPID_PROBE4(asynchio_read_finished_done, &h, duration, total, readCalls); break; } // Stop reading if we've overrun our timeslot if ( duration > threadMaxIoTimeNs) { QPID_PROBE4(asynchio_read_finished_maxtime, &h, duration, total, readCalls); break; } } else { // Put buffer back (at front so it doesn't interfere with unread buffers) bufferQueue.push_front(buff); assert(buff); QPID_PROBE5(asynchio_read_finished_error, &h, duration, total, readCalls, errno); // Eof or other side has gone away if (rc == 0 || errno == ECONNRESET) { eofCallback(*this); h.unwatchRead(); break; } else if (errno == EAGAIN) { // We have just put a buffer back so we know // we can carry on watching for reads break; } else { // Report error then just treat as a socket disconnect QPID_LOG(error, "Error reading socket: " << qpid::sys::strError(errno) << "(" << errno << ")" ); eofCallback(*this); h.unwatchRead(); break; } } } else { // Something to read but no buffer if (emptyCallback) { emptyCallback(*this); } // If we still have no buffers we can't do anything more if (bufferQueue.empty()) { h.unwatchRead(); QPID_PROBE4(asynchio_read_finished_nobuffers, &h, Duration(readStartTime, AbsTime::now()), total, readCalls); break; } } } while (true); ++threadReadCount; return; }
/* * We keep on reading as long as we have something to read and a buffer to put * it in */ void SslIO::readable(DispatchHandle& h) { AbsTime readStartTime = AbsTime::now(); do { // (Try to) get a buffer if (!bufferQueue.empty()) { // Read into buffer BufferBase* buff = bufferQueue.front(); assert(buff); bufferQueue.pop_front(); errno = 0; int readCount = buff->byteCount-buff->dataCount; int rc = socket.read(buff->bytes + buff->dataCount, readCount); if (rc > 0) { buff->dataCount += rc; threadReadTotal += rc; readCallback(*this, buff); if (rc != readCount) { // If we didn't fill the read buffer then time to stop reading break; } // Stop reading if we've overrun our timeslot if (Duration(readStartTime, AbsTime::now()) > threadMaxIoTimeNs) { break; } } else { // Put buffer back (at front so it doesn't interfere with unread buffers) bufferQueue.push_front(buff); assert(buff); // Eof or other side has gone away if (rc == 0 || errno == ECONNRESET) { eofCallback(*this); h.unwatchRead(); break; } else if (errno == EAGAIN) { // We have just put a buffer back so we know // we can carry on watching for reads break; } else { // Report error then just treat as a socket disconnect QPID_LOG(error, "Error reading socket: " << getErrorString(PR_GetError())); eofCallback(*this); h.unwatchRead(); break; } } } else { // Something to read but no buffer if (emptyCallback) { emptyCallback(*this); } // If we still have no buffers we can't do anything more if (bufferQueue.empty()) { h.unwatchRead(); break; } } } while (true); ++threadReadCount; return; }