Write.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 #include "squid.h"
10 #include "cbdata.h"
11 #include "comm/Connection.h"
12 #include "comm/IoCallback.h"
13 #include "comm/Loops.h"
14 #include "comm/Write.h"
15 #include "fd.h"
16 #include "fde.h"
17 #include "globals.h"
18 #include "MemBuf.h"
19 #include "profiler/Profiler.h"
20 #include "SquidTime.h"
21 #include "StatCounters.h"
22 #if USE_DELAY_POOLS
23 #include "ClientInfo.h"
24 #endif
25 
26 #include <cerrno>
27 
28 void
30 {
31  Comm::Write(conn, mb->buf, mb->size, callback, mb->freeFunc());
32 }
33 
34 void
36 {
37  debugs(5, 5, HERE << conn << ": sz " << size << ": asynCall " << callback);
38 
39  /* Make sure we are open, not closing, and not writing */
40  assert(fd_table[conn->fd].flags.open);
41  assert(!fd_table[conn->fd].closing());
42  Comm::IoCallback *ccb = COMMIO_FD_WRITECB(conn->fd);
43  assert(!ccb->active());
44 
45  fd_table[conn->fd].writeStart = squid_curtime;
46  ccb->conn = conn;
47  /* Queue the write */
48  ccb->setCallback(IOCB_WRITE, callback, (char *)buf, free_func, size);
49  ccb->selectOrQueueWrite();
50 }
51 
57 void
58 Comm::HandleWrite(int fd, void *data)
59 {
60  Comm::IoCallback *state = static_cast<Comm::IoCallback *>(data);
61  int len = 0;
62  int nleft;
63 
64  assert(state->conn != NULL);
65  assert(state->conn->fd == fd);
66 
67  PROF_start(commHandleWrite);
68  debugs(5, 5, HERE << state->conn << ": off " <<
69  (long int) state->offset << ", sz " << (long int) state->size << ".");
70 
71  nleft = state->size - state->offset;
72 
73 #if USE_DELAY_POOLS
75  if (bucket) {
76  assert(bucket->selectWaiting);
77  bucket->selectWaiting = false;
78  if (nleft > 0 && !bucket->applyQuota(nleft, state)) {
79  PROF_stop(commHandleWrite);
80  return;
81  }
82  }
83 #endif /* USE_DELAY_POOLS */
84 
85  /* actually WRITE data */
86  int xerrno = errno = 0;
87  len = FD_WRITE_METHOD(fd, state->buf + state->offset, nleft);
88  xerrno = errno;
89  debugs(5, 5, HERE << "write() returns " << len);
90 
91 #if USE_DELAY_POOLS
92  if (bucket) {
93  /* we wrote data - drain them from bucket */
94  bucket->reduceBucket(len);
95  }
96 #endif /* USE_DELAY_POOLS */
97 
98  fd_bytes(fd, len, FD_WRITE);
99  ++statCounter.syscalls.sock.writes;
100  // After each successful partial write,
101  // reset fde::writeStart to the current time.
102  fd_table[fd].writeStart = squid_curtime;
103 
104  if (len == 0) {
105  /* Note we even call write if nleft == 0 */
106  /* We're done */
107  if (nleft != 0)
108  debugs(5, DBG_IMPORTANT, "FD " << fd << " write failure: connection closed with " << nleft << " bytes remaining.");
109 
110  state->finish(nleft ? Comm::COMM_ERROR : Comm::OK, 0);
111  } else if (len < 0) {
112  /* An error */
113  if (fd_table[fd].flags.socket_eof) {
114  debugs(50, 2, "FD " << fd << " write failure: " << xstrerr(xerrno) << ".");
115  state->finish(nleft ? Comm::COMM_ERROR : Comm::OK, xerrno);
116  } else if (ignoreErrno(xerrno)) {
117  debugs(50, 9, "FD " << fd << " write failure: " << xstrerr(xerrno) << ".");
118  state->selectOrQueueWrite();
119  } else {
120  debugs(50, 2, "FD " << fd << " write failure: " << xstrerr(xerrno) << ".");
121  state->finish(nleft ? Comm::COMM_ERROR : Comm::OK, xerrno);
122  }
123  } else {
124  /* A successful write, continue */
125  state->offset += len;
126 
127  if (state->offset < state->size) {
128  /* Not done, reinstall the write handler and write some more */
129  state->selectOrQueueWrite();
130  } else {
131  state->finish(nleft ? Comm::OK : Comm::COMM_ERROR, 0);
132  }
133  }
134 
135  PROF_stop(commHandleWrite);
136 }
137 
Base class for Squid-to-client bandwidth limiting.
FREE * freeFunc()
Definition: MemBuf.cc:328
virtual void reduceBucket(const int len)
Decreases the bucket level.
PF HandleWrite
Definition: forward.h:34
#define fd_table
Definition: fde.h:157
StatCounters statCounter
Definition: StatCounters.cc:12
#define assert(EX)
Definition: assert.h:17
void const char HLPCB * callback
Definition: stub_helper.cc:16
void finish(Comm::Flag code, int xerrn)
finish the IO operation imediately and schedule the callback with the current state.
Definition: IoCallback.cc:110
struct StatCounters::@136::@140 sock
Definition: Flag.h:16
Definition: enums.h:24
bool selectWaiting
is between commSetSelect and commHandleWrite
void FREE(void *)
Definition: forward.h:36
int conn
the current server connection FD
Definition: Transport.cc:26
time_t squid_curtime
Definition: stub_time.cc:17
void fd_bytes(int fd, int len, unsigned int type)
Definition: fd.cc:261
const char * xstrerr(int error)
Definition: xstrerror.cc:83
void const char HLPCB void * data
Definition: stub_helper.cc:16
Comm::ConnectionPointer conn
Definition: IoCallback.h:33
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Debug.h:123
struct StatCounters::@136 syscalls
#define DBG_IMPORTANT
Definition: Debug.h:45
mb_size_t size
Definition: MemBuf.h:135
static BandwidthBucket * SelectBucket(fde *f)
void selectOrQueueWrite()
called when fd needs to write but may need to wait in line for its quota
Definition: IoCallback.cc:69
int unsigned int const char *desc STUB void int len
Definition: stub_fd.cc:20
void const char * buf
Definition: stub_helper.cc:16
std::ostream & HERE(std::ostream &s)
Definition: Debug.h:147
#define COMMIO_FD_WRITECB(fd)
Definition: IoCallback.h:79
int ignoreErrno(int ierrno)
Definition: comm.cc:1477
virtual bool applyQuota(int &nleft, Comm::IoCallback *state)
char * buf
Definition: MemBuf.h:134
#define PROF_start(probename)
Definition: Profiler.h:62
Definition: MemBuf.h:23
#define PROF_stop(probename)
Definition: Profiler.h:63
#define FD_WRITE_METHOD(fd, buf, len)
Definition: fde.h:162
#define NULL
Definition: types.h:166
Details about a particular Comm IO callback event.
Definition: IoCallback.h:29
int size
Definition: ModDevPoll.cc:77
void Write(const Comm::ConnectionPointer &conn, const char *buf, int size, AsyncCall::Pointer &callback, FREE *free_func)
Definition: Write.cc:35

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors