]> git.ipfire.org Git - thirdparty/squid.git/blob - src/comm/IoCallback.cc
Merged from trunk rev.14096
[thirdparty/squid.git] / src / comm / IoCallback.cc
1 /*
2 * Copyright (C) 1996-2015 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 "ClientInfo.h"
11 #include "comm/Connection.h"
12 #include "comm/IoCallback.h"
13 #include "comm/Loops.h"
14 #include "comm/Write.h"
15 #include "CommCalls.h"
16 #include "fde.h"
17 #include "globals.h"
18
19 Comm::CbEntry *Comm::iocb_table;
20
21 void
22 Comm::CallbackTableInit()
23 {
24 // XXX: convert this to a std::map<> ?
25 iocb_table = static_cast<CbEntry*>(xcalloc(Squid_MaxFD, sizeof(CbEntry)));
26 for (int pos = 0; pos < Squid_MaxFD; ++pos) {
27 iocb_table[pos].fd = pos;
28 iocb_table[pos].readcb.type = IOCB_READ;
29 iocb_table[pos].writecb.type = IOCB_WRITE;
30 }
31 }
32
33 void
34 Comm::CallbackTableDestruct()
35 {
36 // release any Comm::Connections being held.
37 for (int pos = 0; pos < Squid_MaxFD; ++pos) {
38 iocb_table[pos].readcb.conn = NULL;
39 iocb_table[pos].writecb.conn = NULL;
40 }
41 safe_free(iocb_table);
42 }
43
44 /**
45 * Configure Comm::Callback for I/O
46 *
47 * @param fd filedescriptor
48 * @param t IO callback type (read or write)
49 * @param cb callback
50 * @param buf buffer, if applicable
51 * @param func freefunc, if applicable
52 * @param sz buffer size
53 */
54 void
55 Comm::IoCallback::setCallback(Comm::iocb_type t, AsyncCall::Pointer &cb, char *b, FREE *f, int sz)
56 {
57 assert(!active());
58 assert(type == t);
59 assert(cb != NULL);
60
61 callback = cb;
62 buf = b;
63 freefunc = f;
64 size = sz;
65 offset = 0;
66 }
67
68 void
69 Comm::IoCallback::selectOrQueueWrite()
70 {
71 #if USE_DELAY_POOLS
72 // stand in line if there is one
73 if (ClientInfo *clientInfo = fd_table[conn->fd].clientInfo) {
74 if (clientInfo->writeLimitingActive) {
75 quotaQueueReserv = clientInfo->quotaEnqueue(conn->fd);
76 clientInfo->kickQuotaQueue();
77 return;
78 }
79 }
80 #endif
81
82 SetSelect(conn->fd, COMM_SELECT_WRITE, Comm::HandleWrite, this, 0);
83 }
84
85 void
86 Comm::IoCallback::cancel(const char *reason)
87 {
88 if (!active())
89 return;
90
91 callback->cancel(reason);
92 callback = NULL;
93 reset();
94 }
95
96 void
97 Comm::IoCallback::reset()
98 {
99 conn = NULL;
100 if (freefunc) {
101 freefunc(buf);
102 buf = NULL;
103 freefunc = NULL;
104 }
105 xerrno = 0;
106
107 #if USE_DELAY_POOLS
108 quotaQueueReserv = 0;
109 #endif
110 }
111
112 // Schedule the callback call and clear the callback
113 void
114 Comm::IoCallback::finish(Comm::Flag code, int xerrn)
115 {
116 debugs(5, 3, "called for " << conn << " (" << code << ", " << xerrn << ")");
117 assert(active());
118
119 /* free data */
120 if (freefunc && buf) {
121 freefunc(buf);
122 buf = NULL;
123 freefunc = NULL;
124 }
125
126 if (callback != NULL) {
127 typedef CommIoCbParams Params;
128 Params &params = GetCommParams<Params>(callback);
129 if (conn != NULL) params.fd = conn->fd; // for legacy write handlers...
130 params.conn = conn;
131 params.buf = buf;
132 params.size = offset;
133 params.flag = code;
134 params.xerrno = xerrn;
135 ScheduleCallHere(callback);
136 callback = NULL;
137 }
138
139 /* Reset for next round. */
140 reset();
141 }
142