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