* Plus, it breaks our lame *HalfClosed() detection
*/
+ Must(maybeMakeSpaceAvailable(true));
CommIoCbParams rd(this); // will be expanded with ReadNow results
rd.conn = io.conn;
rd.size = entry->bytesWanted(Range<size_t>(0, inBuf.spaceSize()));
if (!Comm::IsConnOpen(serverConnection) || fd_table[serverConnection->fd].closing())
return;
+ if (!maybeMakeSpaceAvailable(false))
+ return;
+
+ // XXX: get rid of the do_next_read flag
+ // check for the proper reasons preventing read(2)
+ if (!flags.do_next_read)
+ return;
+
+ flags.do_next_read = false;
+
+ // must not already be waiting for read(2) ...
+ assert(!Comm::MonitorsRead(serverConnection->fd));
+
+ // wait for read(2) to be possible.
+ typedef CommCbMemFunT<HttpStateData, CommIoCbParams> Dialer;
+ AsyncCall::Pointer call = JobCallback(11, 5, Dialer, this, HttpStateData::readReply);
+ Comm::Read(serverConnection, call);
+}
+
+bool
+HttpStateData::maybeMakeSpaceAvailable(bool doGrow)
+{
// how much we are allowed to buffer
const int limitBuffer = (flags.headers_parsed ? Config.readAheadGap : Config.maxReplyHeaderSize);
debugs(11, DBG_DATA, "buffer has {" << inBuf << "}");
// Process next response from buffer
processReply();
- return;
+ return false;
}
// how much we want to read
if (!read_size) {
debugs(11, 7, "wont read up to " << read_size << " into buffer (" << inBuf.length() << "/" << inBuf.spaceSize() << ") from " << serverConnection);
- return;
+ return false;
}
+ // just report whether we could grow or not, dont actually do it
+ if (doGrow)
+ return (read_size >= 2);
+
// we may need to grow the buffer
inBuf.reserveSpace(read_size);
debugs(11, 8, (!flags.do_next_read ? "wont" : "may") <<
" read up to " << read_size << " bytes info buf(" << inBuf.length() << "/" << inBuf.spaceSize() <<
") from " << serverConnection);
- // XXX: get rid of the do_next_read flag
- // check for the proper reasons preventing read(2)
- if (!flags.do_next_read)
- return;
-
- flags.do_next_read = false;
-
- // must not already be waiting for read(2) ...
- assert(!Comm::MonitorsRead(serverConnection->fd));
-
- // wait for read(2) to be possible.
- typedef CommCbMemFunT<HttpStateData, CommIoCbParams> Dialer;
- AsyncCall::Pointer call = JobCallback(11, 5, Dialer, this, HttpStateData::readReply);
- Comm::Read(serverConnection, call);
+ return (inBuf.spaceSize() >= 2); // only read if there is 1+ bytes of space available
}
/// called after writing the very last request byte (body, last-chunk, etc)
virtual void abortTransaction(const char *reason); // abnormal termination
virtual bool mayReadVirginReplyBody() const;
+ /**
+ * determine if read buffer can have space made available
+ * for a read.
+ *
+ * \param grow whether to actually expand the buffer
+ *
+ * \return whether the buffer can be grown to provide space
+ * regardless of whether the grow actually happened.
+ */
+ bool maybeMakeSpaceAvailable(bool grow);
+
// consuming request body
virtual void handleMoreRequestBodyAvailable();
virtual void handleRequestBodyProducerAborted();