]> git.ipfire.org Git - thirdparty/squid.git/blob - src/comm/IoCallback.cc
Source Format Enforcement (#532)
[thirdparty/squid.git] / src / comm / IoCallback.cc
1 /*
2 * Copyright (C) 1996-2020 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 if (BandwidthBucket *bucket = BandwidthBucket::SelectBucket(&fd_table[conn->fd])) {
73 bucket->scheduleWrite(this);
74 return;
75 }
76 #endif
77
78 SetSelect(conn->fd, COMM_SELECT_WRITE, Comm::HandleWrite, this, 0);
79 }
80
81 void
82 Comm::IoCallback::cancel(const char *reason)
83 {
84 if (!active())
85 return;
86
87 callback->cancel(reason);
88 callback = NULL;
89 reset();
90 }
91
92 void
93 Comm::IoCallback::reset()
94 {
95 conn = NULL;
96 if (freefunc) {
97 freefunc(buf);
98 buf = NULL;
99 freefunc = NULL;
100 }
101 xerrno = 0;
102
103 #if USE_DELAY_POOLS
104 quotaQueueReserv = 0;
105 #endif
106 }
107
108 // Schedule the callback call and clear the callback
109 void
110 Comm::IoCallback::finish(Comm::Flag code, int xerrn)
111 {
112 debugs(5, 3, "called for " << conn << " (" << code << ", " << xerrn << ")");
113 assert(active());
114
115 /* free data */
116 if (freefunc && buf) {
117 freefunc(buf);
118 buf = NULL;
119 freefunc = NULL;
120 }
121
122 if (callback != NULL) {
123 typedef CommIoCbParams Params;
124 Params &params = GetCommParams<Params>(callback);
125 if (conn != NULL) params.fd = conn->fd; // for legacy write handlers...
126 params.conn = conn;
127 params.buf = buf;
128 params.size = offset;
129 params.flag = code;
130 params.xerrno = xerrn;
131 ScheduleCallHere(callback);
132 callback = NULL;
133 }
134
135 /* Reset for next round. */
136 reset();
137 }
138