]>
Commit | Line | Data |
---|---|---|
8822ebee | 1 | /* |
b8ae064d | 2 | * Copyright (C) 1996-2023 The Squid Software Foundation and contributors |
8822ebee | 3 | * |
bbc27441 AJ |
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. | |
8822ebee AR |
7 | */ |
8 | ||
bbc27441 AJ |
9 | /* DEBUG: section 16 Cache Manager API */ |
10 | ||
f7f3304a | 11 | #include "squid.h" |
7e9f330d | 12 | #include "base/AsyncCbdataCalls.h" |
8822ebee | 13 | #include "base/TextException.h" |
a928fdfd | 14 | #include "comm.h" |
c3e8e4e9 | 15 | #include "comm/Connection.h" |
ec41b64c | 16 | #include "comm/Write.h" |
602d9612 | 17 | #include "CommCalls.h" |
8822ebee AR |
18 | #include "ipc/FdNotes.h" |
19 | #include "mgr/StoreToCommWriter.h" | |
8822ebee | 20 | #include "Store.h" |
602d9612 | 21 | #include "StoreClient.h" |
8822ebee | 22 | |
c3e8e4e9 | 23 | Mgr::StoreToCommWriter::StoreToCommWriter(const Comm::ConnectionPointer &conn, StoreEntry* anEntry): |
f53969cc | 24 | AsyncJob("Mgr::StoreToCommWriter"), |
aee3523a | 25 | clientConnection(conn), entry(anEntry), sc(nullptr), writeOffset(0), closer(nullptr) |
8822ebee | 26 | { |
bf95c10a | 27 | debugs(16, 6, clientConnection); |
8822ebee | 28 | closer = asyncCall(16, 5, "Mgr::StoreToCommWriter::noteCommClosed", |
d9fc6862 | 29 | CommCbMemFunT<StoreToCommWriter, CommCloseCbParams>(this, &StoreToCommWriter::noteCommClosed)); |
c3e8e4e9 | 30 | comm_add_close_handler(clientConnection->fd, closer); |
8822ebee AR |
31 | } |
32 | ||
33 | Mgr::StoreToCommWriter::~StoreToCommWriter() | |
34 | { | |
bf95c10a | 35 | debugs(16, 6, MYNAME); |
8822ebee AR |
36 | assert(!entry); |
37 | assert(!sc); | |
38 | close(); | |
39 | } | |
40 | ||
41 | /// closes our copy of the client HTTP connection socket | |
42 | void | |
43 | Mgr::StoreToCommWriter::close() | |
44 | { | |
c3e8e4e9 | 45 | if (Comm::IsConnOpen(clientConnection)) { |
aee3523a | 46 | if (closer != nullptr) { |
c3e8e4e9 | 47 | comm_remove_close_handler(clientConnection->fd, closer); |
aee3523a | 48 | closer = nullptr; |
8822ebee | 49 | } |
c3e8e4e9 | 50 | clientConnection->close(); |
8822ebee AR |
51 | } |
52 | } | |
53 | ||
54 | void | |
55 | Mgr::StoreToCommWriter::start() | |
56 | { | |
bf95c10a | 57 | debugs(16, 6, MYNAME); |
c3e8e4e9 | 58 | Must(Comm::IsConnOpen(clientConnection)); |
aee3523a | 59 | Must(entry != nullptr); |
7e9f330d EB |
60 | AsyncCall::Pointer call = asyncCall(16, 4, "StoreToCommWriter::Abort", cbdataDialer(&StoreToCommWriter::HandleStoreAbort, this)); |
61 | entry->registerAbortCallback(call); | |
8822ebee | 62 | sc = storeClientListAdd(entry, this); |
aee3523a | 63 | Must(sc != nullptr); |
8822ebee AR |
64 | |
65 | // initiate the receive-from-store, write-to-comm sequence | |
66 | scheduleStoreCopy(); | |
67 | } | |
68 | ||
69 | void | |
70 | Mgr::StoreToCommWriter::scheduleStoreCopy() | |
71 | { | |
bf95c10a | 72 | debugs(16, 6, MYNAME); |
aee3523a AR |
73 | Must(entry != nullptr); |
74 | Must(sc != nullptr); | |
8822ebee AR |
75 | StoreIOBuffer readBuf(sizeof(buffer), writeOffset, buffer); |
76 | storeClientCopy(sc, entry, readBuf, &NoteStoreCopied, this); | |
77 | } | |
78 | ||
79 | void | |
80 | Mgr::StoreToCommWriter::NoteStoreCopied(void* data, StoreIOBuffer ioBuf) | |
81 | { | |
aee3523a | 82 | Must(data != nullptr); |
8822ebee AR |
83 | // make sync Store call async to get async call protections and features |
84 | StoreToCommWriter* writer = static_cast<StoreToCommWriter*>(data); | |
85 | typedef UnaryMemFunT<StoreToCommWriter, StoreIOBuffer> MyDialer; | |
86 | AsyncCall::Pointer call = | |
87 | asyncCall(16, 5, "Mgr::StoreToCommWriter::noteStoreCopied", | |
d9fc6862 | 88 | MyDialer(writer, &StoreToCommWriter::noteStoreCopied, ioBuf)); |
8822ebee AR |
89 | ScheduleCallHere(call); |
90 | } | |
91 | ||
92 | void | |
93 | Mgr::StoreToCommWriter::noteStoreCopied(StoreIOBuffer ioBuf) | |
94 | { | |
bf95c10a | 95 | debugs(16, 6, MYNAME); |
8822ebee AR |
96 | Must(!ioBuf.flags.error); |
97 | if (ioBuf.length > 0) | |
98 | scheduleCommWrite(ioBuf); // write received action results to client | |
99 | else | |
100 | Must(doneAll()); // otherwise, why would Store call us with no data? | |
101 | } | |
102 | ||
103 | void | |
104 | Mgr::StoreToCommWriter::scheduleCommWrite(const StoreIOBuffer& ioBuf) | |
105 | { | |
bf95c10a | 106 | debugs(16, 6, MYNAME); |
c3e8e4e9 | 107 | Must(Comm::IsConnOpen(clientConnection)); |
aee3523a | 108 | Must(ioBuf.data != nullptr); |
8822ebee AR |
109 | // write filled buffer |
110 | typedef CommCbMemFunT<StoreToCommWriter, CommIoCbParams> MyDialer; | |
111 | AsyncCall::Pointer writer = | |
112 | asyncCall(16, 5, "Mgr::StoreToCommWriter::noteCommWrote", | |
d9fc6862 | 113 | MyDialer(this, &StoreToCommWriter::noteCommWrote)); |
aee3523a | 114 | Comm::Write(clientConnection, ioBuf.data, ioBuf.length, writer, nullptr); |
8822ebee AR |
115 | } |
116 | ||
117 | void | |
118 | Mgr::StoreToCommWriter::noteCommWrote(const CommIoCbParams& params) | |
119 | { | |
bf95c10a | 120 | debugs(16, 6, MYNAME); |
c8407295 | 121 | Must(params.flag == Comm::OK); |
aee3523a | 122 | Must(clientConnection != nullptr && params.fd == clientConnection->fd); |
8822ebee AR |
123 | Must(params.size != 0); |
124 | writeOffset += params.size; | |
125 | if (!doneAll()) | |
126 | scheduleStoreCopy(); // retrieve the next data portion | |
127 | } | |
128 | ||
129 | void | |
ced8def3 | 130 | Mgr::StoreToCommWriter::noteCommClosed(const CommCloseCbParams &) |
8822ebee | 131 | { |
bf95c10a | 132 | debugs(16, 6, MYNAME); |
2b6b1bcb AR |
133 | if (clientConnection) { |
134 | clientConnection->noteClosure(); | |
135 | clientConnection = nullptr; | |
136 | } | |
137 | closer = nullptr; | |
8822ebee AR |
138 | mustStop("commClosed"); |
139 | } | |
140 | ||
141 | void | |
142 | Mgr::StoreToCommWriter::swanSong() | |
143 | { | |
bf95c10a | 144 | debugs(16, 6, MYNAME); |
aee3523a AR |
145 | if (entry != nullptr) { |
146 | if (sc != nullptr) { | |
8822ebee | 147 | storeUnregister(sc, entry, this); |
aee3523a | 148 | sc = nullptr; |
8822ebee | 149 | } |
7e9f330d | 150 | entry->unregisterAbortCallback("StoreToCommWriter done"); |
acc5dc4c | 151 | entry->unlock("Mgr::StoreToCommWriter::swanSong"); |
aee3523a | 152 | entry = nullptr; |
8822ebee AR |
153 | } |
154 | close(); | |
155 | } | |
156 | ||
157 | bool | |
158 | Mgr::StoreToCommWriter::doneAll() const | |
159 | { | |
160 | return entry && | |
d9fc6862 A |
161 | entry->store_status == STORE_OK && // the action is over |
162 | writeOffset >= entry->objectLen(); // we wrote all the results | |
8822ebee AR |
163 | } |
164 | ||
165 | void | |
7e9f330d | 166 | Mgr::StoreToCommWriter::HandleStoreAbort(StoreToCommWriter *mgrWriter) |
8822ebee | 167 | { |
c3e8e4e9 AJ |
168 | if (Comm::IsConnOpen(mgrWriter->clientConnection)) |
169 | mgrWriter->clientConnection->close(); | |
8822ebee | 170 | } |
f53969cc | 171 |