]> git.ipfire.org Git - thirdparty/squid.git/blame - src/mgr/StoreToCommWriter.cc
Source Format Enforcement (#1234)
[thirdparty/squid.git] / src / mgr / StoreToCommWriter.cc
CommitLineData
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 23Mgr::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
33Mgr::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
42void
43Mgr::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
54void
55Mgr::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
69void
70Mgr::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
79void
80Mgr::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
92void
93Mgr::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
103void
104Mgr::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
117void
118Mgr::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
129void
ced8def3 130Mgr::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
141void
142Mgr::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
157bool
158Mgr::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
165void
7e9f330d 166Mgr::StoreToCommWriter::HandleStoreAbort(StoreToCommWriter *mgrWriter)
8822ebee 167{
c3e8e4e9
AJ
168 if (Comm::IsConnOpen(mgrWriter->clientConnection))
169 mgrWriter->clientConnection->close();
8822ebee 170}
f53969cc 171