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