101d6381dSPawel Dziepak /*
201d6381dSPawel Dziepak * Copyright 2012 Haiku, Inc. All rights reserved.
301d6381dSPawel Dziepak * Distributed under the terms of the MIT License.
401d6381dSPawel Dziepak *
501d6381dSPawel Dziepak * Authors:
601d6381dSPawel Dziepak * Paweł Dziepak, pdziepak@quarnos.org
701d6381dSPawel Dziepak */
801d6381dSPawel Dziepak
901d6381dSPawel Dziepak
1001d6381dSPawel Dziepak #include "Request.h"
1101d6381dSPawel Dziepak
12060a4636SPawel Dziepak #include "FileSystem.h"
13060a4636SPawel Dziepak #include "Inode.h"
14060a4636SPawel Dziepak
1501d6381dSPawel Dziepak
1601d6381dSPawel Dziepak status_t
Send(Cookie * cookie)17be4c74eaSPawel Dziepak Request::Send(Cookie* cookie)
1801d6381dSPawel Dziepak {
195945c55aSPawel Dziepak switch (fServer->ID().fProtocol) {
20c3b57e8eSPawel Dziepak case IPPROTO_UDP: return _SendUDP(cookie);
21c3b57e8eSPawel Dziepak case IPPROTO_TCP: return _SendTCP(cookie);
225945c55aSPawel Dziepak }
235945c55aSPawel Dziepak
245945c55aSPawel Dziepak return B_BAD_VALUE;
253ce57b34SPawel Dziepak }
263ce57b34SPawel Dziepak
273ce57b34SPawel Dziepak
283ce57b34SPawel Dziepak status_t
_SendUDP(Cookie * cookie)29be4c74eaSPawel Dziepak Request::_SendUDP(Cookie* cookie)
303ce57b34SPawel Dziepak {
31be4c74eaSPawel Dziepak RPC::Reply* rpl = NULL;
323ce57b34SPawel Dziepak RPC::Request* rpc;
333ce57b34SPawel Dziepak
343ce57b34SPawel Dziepak status_t result = fServer->SendCallAsync(fBuilder.Request(), &rpl, &rpc);
3501d6381dSPawel Dziepak if (result != B_OK)
3601d6381dSPawel Dziepak return result;
3701d6381dSPawel Dziepak
38be4c74eaSPawel Dziepak if (cookie != NULL)
39be4c74eaSPawel Dziepak cookie->RegisterRequest(rpc);
40be4c74eaSPawel Dziepak
41e4cd963fSPawel Dziepak int requestTimeout = sSecToBigTime(60);
42060a4636SPawel Dziepak int retryLimit = 0;
43060a4636SPawel Dziepak bool hard = true;
44e4cd963fSPawel Dziepak
45060a4636SPawel Dziepak if (fFileSystem != NULL) {
46e4cd963fSPawel Dziepak requestTimeout = fFileSystem->GetConfiguration().fRequestTimeout;
47060a4636SPawel Dziepak retryLimit = fFileSystem->GetConfiguration().fRetryLimit;
48060a4636SPawel Dziepak hard = fFileSystem->GetConfiguration().fHard;
49060a4636SPawel Dziepak }
50060a4636SPawel Dziepak
51e4cd963fSPawel Dziepak result = fServer->WaitCall(rpc, requestTimeout);
523ce57b34SPawel Dziepak if (result != B_OK) {
535945c55aSPawel Dziepak int attempts = 1;
54060a4636SPawel Dziepak while (result != B_OK && (hard || attempts++ < retryLimit)) {
555945c55aSPawel Dziepak result = fServer->ResendCallAsync(fBuilder.Request(), rpc);
56be4c74eaSPawel Dziepak if (result != B_OK) {
57be4c74eaSPawel Dziepak if (cookie != NULL)
58be4c74eaSPawel Dziepak cookie->UnregisterRequest(rpc);
59*b6868c6eSPawel Dziepak delete rpc;
600792abe0SPawel Dziepak return result;
61be4c74eaSPawel Dziepak }
625945c55aSPawel Dziepak
63e4cd963fSPawel Dziepak result = fServer->WaitCall(rpc, requestTimeout);
640792abe0SPawel Dziepak }
650792abe0SPawel Dziepak
660792abe0SPawel Dziepak if (result != B_OK) {
67be4c74eaSPawel Dziepak if (cookie != NULL)
68be4c74eaSPawel Dziepak cookie->UnregisterRequest(rpc);
693ce57b34SPawel Dziepak fServer->CancelCall(rpc);
703ce57b34SPawel Dziepak delete rpc;
713ce57b34SPawel Dziepak return result;
723ce57b34SPawel Dziepak }
735945c55aSPawel Dziepak }
745945c55aSPawel Dziepak
75be4c74eaSPawel Dziepak if (cookie != NULL)
76be4c74eaSPawel Dziepak cookie->UnregisterRequest(rpc);
77be4c74eaSPawel Dziepak
78be4c74eaSPawel Dziepak if (rpc->fError != B_OK) {
79be4c74eaSPawel Dziepak delete rpl;
80be4c74eaSPawel Dziepak result = rpc->fError;
81be4c74eaSPawel Dziepak delete rpc;
82be4c74eaSPawel Dziepak return result;
83be4c74eaSPawel Dziepak } else {
84be4c74eaSPawel Dziepak fReply.SetTo(rpl);
85be4c74eaSPawel Dziepak delete rpc;
86be4c74eaSPawel Dziepak return B_OK;
87be4c74eaSPawel Dziepak }
885945c55aSPawel Dziepak }
895945c55aSPawel Dziepak
905945c55aSPawel Dziepak
915945c55aSPawel Dziepak status_t
_SendTCP(Cookie * cookie)92be4c74eaSPawel Dziepak Request::_SendTCP(Cookie* cookie)
935945c55aSPawel Dziepak {
94be4c74eaSPawel Dziepak RPC::Reply* rpl = NULL;
955945c55aSPawel Dziepak RPC::Request* rpc;
965945c55aSPawel Dziepak
975945c55aSPawel Dziepak status_t result;
985945c55aSPawel Dziepak int attempts = 0;
99060a4636SPawel Dziepak
100e4cd963fSPawel Dziepak int requestTimeout = sSecToBigTime(60);
101060a4636SPawel Dziepak int retryLimit = 0;
102060a4636SPawel Dziepak bool hard = true;
103060a4636SPawel Dziepak
104060a4636SPawel Dziepak if (fFileSystem != NULL) {
105e4cd963fSPawel Dziepak requestTimeout = fFileSystem->GetConfiguration().fRequestTimeout;
106060a4636SPawel Dziepak retryLimit = fFileSystem->GetConfiguration().fRetryLimit;
107060a4636SPawel Dziepak hard = fFileSystem->GetConfiguration().fHard;
108060a4636SPawel Dziepak }
109060a4636SPawel Dziepak
1105945c55aSPawel Dziepak do {
1115945c55aSPawel Dziepak result = fServer->SendCallAsync(fBuilder.Request(), &rpl, &rpc);
1125945c55aSPawel Dziepak if (result == B_NO_MEMORY)
1135945c55aSPawel Dziepak return result;
1145945c55aSPawel Dziepak else if (result != B_OK) {
1155945c55aSPawel Dziepak fServer->Repair();
1165945c55aSPawel Dziepak continue;
1175945c55aSPawel Dziepak }
1185945c55aSPawel Dziepak
119be4c74eaSPawel Dziepak if (cookie != NULL)
120be4c74eaSPawel Dziepak cookie->RegisterRequest(rpc);
121be4c74eaSPawel Dziepak
122e4cd963fSPawel Dziepak result = fServer->WaitCall(rpc, requestTimeout);
1235945c55aSPawel Dziepak if (result != B_OK) {
124be4c74eaSPawel Dziepak if (cookie != NULL)
125be4c74eaSPawel Dziepak cookie->UnregisterRequest(rpc);
126be4c74eaSPawel Dziepak
1275945c55aSPawel Dziepak fServer->CancelCall(rpc);
1285945c55aSPawel Dziepak delete rpc;
1295945c55aSPawel Dziepak
1305945c55aSPawel Dziepak fServer->Repair();
1315945c55aSPawel Dziepak }
132060a4636SPawel Dziepak } while (result != B_OK && (hard || attempts++ < retryLimit));
1333ce57b34SPawel Dziepak
134e8ef557aSPawel Dziepak if (result != B_OK)
135e8ef557aSPawel Dziepak return result;
136e8ef557aSPawel Dziepak
137be4c74eaSPawel Dziepak if (cookie != NULL)
138be4c74eaSPawel Dziepak cookie->UnregisterRequest(rpc);
139be4c74eaSPawel Dziepak
140be4c74eaSPawel Dziepak if (rpc->fError != B_OK) {
141be4c74eaSPawel Dziepak delete rpl;
142be4c74eaSPawel Dziepak result = rpc->fError;
143be4c74eaSPawel Dziepak delete rpc;
144be4c74eaSPawel Dziepak return result;
145e8ef557aSPawel Dziepak }
146e8ef557aSPawel Dziepak
147be4c74eaSPawel Dziepak fReply.SetTo(rpl);
148be4c74eaSPawel Dziepak delete rpc;
149be4c74eaSPawel Dziepak return B_OK;
15001d6381dSPawel Dziepak }
15101d6381dSPawel Dziepak
15201d6381dSPawel Dziepak
15301d6381dSPawel Dziepak void
Reset()15401d6381dSPawel Dziepak Request::Reset()
15501d6381dSPawel Dziepak {
15601d6381dSPawel Dziepak fBuilder.Reset();
15701d6381dSPawel Dziepak fReply.Reset();
15801d6381dSPawel Dziepak }
15901d6381dSPawel Dziepak
160