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