]> git.ipfire.org Git - thirdparty/squid.git/blame - src/comm/IoCallback.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / comm / IoCallback.cc
CommitLineData
bbc27441 1/*
4ac4a490 2 * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
bbc27441
AJ
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
f7f3304a 9#include "squid.h"
ec41b64c 10#include "ClientInfo.h"
b0388924 11#include "comm/Connection.h"
ec41b64c 12#include "comm/IoCallback.h"
d841c88d 13#include "comm/Loops.h"
ec41b64c
AJ
14#include "comm/Write.h"
15#include "CommCalls.h"
16#include "fde.h"
582c2af2 17#include "globals.h"
ec41b64c
AJ
18
19Comm::CbEntry *Comm::iocb_table;
20
21void
22Comm::CallbackTableInit()
23{
24 // XXX: convert this to a std::map<> ?
25 iocb_table = static_cast<CbEntry*>(xcalloc(Squid_MaxFD, sizeof(CbEntry)));
cbebe602 26 for (int pos = 0; pos < Squid_MaxFD; ++pos) {
ec41b64c 27 iocb_table[pos].fd = pos;
ec41b64c 28 iocb_table[pos].readcb.type = IOCB_READ;
ec41b64c
AJ
29 iocb_table[pos].writecb.type = IOCB_WRITE;
30 }
31}
32
33void
34Comm::CallbackTableDestruct()
35{
b0388924 36 // release any Comm::Connections being held.
cbebe602 37 for (int pos = 0; pos < Squid_MaxFD; ++pos) {
b0388924
AJ
38 iocb_table[pos].readcb.conn = NULL;
39 iocb_table[pos].writecb.conn = NULL;
40 }
ec41b64c
AJ
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 */
54void
55Comm::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
68void
69Comm::IoCallback::selectOrQueueWrite()
70{
9a0a18de 71#if USE_DELAY_POOLS
ec41b64c 72 // stand in line if there is one
b0388924 73 if (ClientInfo *clientInfo = fd_table[conn->fd].clientInfo) {
ec41b64c 74 if (clientInfo->writeLimitingActive) {
b0388924 75 quotaQueueReserv = clientInfo->quotaEnqueue(conn->fd);
ec41b64c
AJ
76 clientInfo->kickQuotaQueue();
77 return;
78 }
79 }
80#endif
81
8bbb16e3 82 SetSelect(conn->fd, COMM_SELECT_WRITE, Comm::HandleWrite, this, 0);
ec41b64c
AJ
83}
84
85void
86Comm::IoCallback::cancel(const char *reason)
87{
88 if (!active())
89 return;
90
91 callback->cancel(reason);
92 callback = NULL;
93 reset();
94}
95
96void
97Comm::IoCallback::reset()
98{
b0388924 99 conn = NULL;
ec41b64c
AJ
100 if (freefunc) {
101 freefunc(buf);
102 buf = NULL;
103 freefunc = NULL;
104 }
105 xerrno = 0;
106
9a0a18de 107#if USE_DELAY_POOLS
ec41b64c
AJ
108 quotaQueueReserv = 0;
109#endif
110}
111
112// Schedule the callback call and clear the callback
113void
c8407295 114Comm::IoCallback::finish(Comm::Flag code, int xerrn)
ec41b64c 115{
872a54ba 116 debugs(5, 3, "called for " << conn << " (" << code << ", " << xerrn << ")");
ec41b64c
AJ
117 assert(active());
118
119 /* free data */
5ddf7edc 120 if (freefunc && buf) {
ec41b64c
AJ
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);
b0388924
AJ
129 if (conn != NULL) params.fd = conn->fd; // for legacy write handlers...
130 params.conn = conn;
ec41b64c
AJ
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}
f53969cc 142