/*
- * DEBUG: section 05 Socket Functions
+ * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
*/
+
+/* DEBUG: section 05 Socket Functions */
+
#include "squid.h"
#include "comm.h"
-#include "comm_internal.h"
-#include "CommCalls.h"
#include "comm/IoCallback.h"
#include "comm/Loops.h"
#include "comm/Read.h"
+#include "comm_internal.h"
+#include "CommCalls.h"
#include "Debug.h"
#include "fd.h"
#include "fde.h"
-#include "SBuf.h"
+#include "sbuf/SBuf.h"
+#include "SquidConfig.h"
#include "StatCounters.h"
-//#include "tools.h"
// Does comm check this fd for read readiness?
// Note that when comm is not monitoring, there can be a pending callback
bool
Comm::MonitorsRead(int fd)
{
- assert(isOpen(fd) && COMMIO_FD_READCB(fd));
+ assert(isOpen(fd) && COMMIO_FD_READCB(fd) != NULL);
// Being active is usually the same as monitoring because we always
// start monitoring the FD when we configure Comm::IoCallback for I/O
// and we usually configure Comm::IoCallback for I/O when we starting
{
/* Attempt a read */
++ statCounter.syscalls.sock.reads;
- const SBuf::size_type sz = buf.spaceSize();
- char *theBuf = buf.rawSpace(sz);
+ SBuf::size_type sz = buf.spaceSize();
+ if (params.size > 0 && params.size < sz)
+ sz = params.size;
+ char *inbuf = buf.rawAppendStart(sz);
errno = 0;
- const int retval = FD_READ_METHOD(params.conn->fd, theBuf, sz);
+ const int retval = FD_READ_METHOD(params.conn->fd, inbuf, sz);
params.xerrno = errno;
debugs(5, 3, params.conn << ", size " << sz << ", retval " << retval << ", errno " << params.xerrno);
if (retval > 0) { // data read most common case
- buf.append(theBuf, retval);
+ buf.rawAppendFinish(inbuf, retval);
fd_bytes(params.conn->fd, retval, FD_READ);
params.flag = Comm::OK;
params.size = retval;
} else if (retval == 0) { // remote closure (somewhat less) common
// Note - read 0 == socket EOF, which is a valid read.
params.flag = Comm::ENDFILE;
+ params.size = 0;
} else if (retval < 0) { // connection errors are worst-case
- debugs(5, 3, params.conn << " Comm::ERROR: " << xstrerr(params.xerrno));
+ debugs(5, 3, params.conn << " Comm::COMM_ERROR: " << xstrerr(params.xerrno));
if (ignoreErrno(params.xerrno))
params.flag = Comm::INPROGRESS;
else
- params.flag = Comm::ERROR;
+ params.flag = Comm::COMM_ERROR;
+ params.size = 0;
}
return params.flag;
assert(data == COMMIO_FD_READCB(fd));
assert(ccb->active());
- // without a buffer, just call back
+ // Without a buffer, just call back.
+ // The callee may ReadMore() to get the data.
if (!ccb->buf) {
ccb->finish(Comm::OK, 0);
return;
/* For legacy callers : Attempt a read */
// Keep in sync with Comm::ReadNow()!
++ statCounter.syscalls.sock.reads;
- errno = 0;
+ int xerrno = errno = 0;
int retval = FD_READ_METHOD(fd, ccb->buf, ccb->size);
- debugs(5, 3, "FD " << fd << ", size " << ccb->size << ", retval " << retval << ", errno " << errno);
+ xerrno = errno;
+ debugs(5, 3, "FD " << fd << ", size " << ccb->size << ", retval " << retval << ", errno " << xerrno);
/* See if we read anything */
/* Note - read 0 == socket EOF, which is a valid read */
if (retval >= 0) {
fd_bytes(fd, retval, FD_READ);
ccb->offset = retval;
- ccb->finish(Comm::OK, errno);
+ ccb->finish(Comm::OK, 0);
return;
-
- } else if (retval < 0 && !ignoreErrno(errno)) {
- debugs(5, 3, "comm_read_try: scheduling Comm::ERROR");
+ } else if (retval < 0 && !ignoreErrno(xerrno)) {
+ debugs(5, 3, "comm_read_try: scheduling Comm::COMM_ERROR");
ccb->offset = 0;
- ccb->finish(Comm::ERROR, errno);
+ ccb->finish(Comm::COMM_ERROR, xerrno);
return;
};
-
/* Nope, register for some more IO */
Comm::SetSelect(fd, COMM_SELECT_READ, Comm::HandleRead, data, 0);
}
/* And the IO event */
Comm::SetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
}
+
+time_t
+Comm::MortalReadTimeout(const time_t startTime, const time_t lifetimeLimit)
+{
+ if (lifetimeLimit > 0) {
+ const time_t timeUsed = (squid_curtime > startTime) ? (squid_curtime - startTime) : 0;
+ const time_t timeLeft = (lifetimeLimit > timeUsed) ? (lifetimeLimit - timeUsed) : 0;
+ return min(::Config.Timeout.read, timeLeft);
+ } else
+ return ::Config.Timeout.read;
+}
+