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