xref: /haiku/src/add-ons/kernel/file_systems/nfs4/Request.cpp (revision 5945c55ae441fb36adca961ed97ab56d978443be)
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 
1201d6381dSPawel Dziepak 
1301d6381dSPawel Dziepak status_t
1401d6381dSPawel Dziepak Request::Send()
1501d6381dSPawel Dziepak {
16*5945c55aSPawel Dziepak 	switch (fServer->ID().fProtocol) {
17*5945c55aSPawel Dziepak 		case ProtocolUDP:	return _SendUDP();
18*5945c55aSPawel Dziepak 		case ProtocolTCP:	return _SendTCP();
19*5945c55aSPawel Dziepak 	}
20*5945c55aSPawel Dziepak 
21*5945c55aSPawel Dziepak 	return B_BAD_VALUE;
223ce57b34SPawel Dziepak }
233ce57b34SPawel Dziepak 
243ce57b34SPawel Dziepak 
253ce57b34SPawel Dziepak status_t
26*5945c55aSPawel Dziepak Request::_SendUDP()
273ce57b34SPawel Dziepak {
2801d6381dSPawel Dziepak 	RPC::Reply *rpl;
293ce57b34SPawel Dziepak 	RPC::Request *rpc;
303ce57b34SPawel Dziepak 
313ce57b34SPawel Dziepak 	status_t result = fServer->SendCallAsync(fBuilder.Request(), &rpl, &rpc);
3201d6381dSPawel Dziepak 	if (result != B_OK)
3301d6381dSPawel Dziepak 		return result;
3401d6381dSPawel Dziepak 
353ce57b34SPawel Dziepak 	result = fServer->WaitCall(rpc);
363ce57b34SPawel Dziepak 	if (result != B_OK) {
37*5945c55aSPawel Dziepak 		int attempts = 1;
38*5945c55aSPawel Dziepak 		while (result != B_OK && attempts++ < kRetryLimit)
39*5945c55aSPawel Dziepak 			result = fServer->ResendCallAsync(fBuilder.Request(), rpc);
40*5945c55aSPawel Dziepak 
41*5945c55aSPawel Dziepak 		if (attempts == kRetryLimit) {
423ce57b34SPawel Dziepak 			fServer->CancelCall(rpc);
433ce57b34SPawel Dziepak 			delete rpc;
443ce57b34SPawel Dziepak 			return result;
453ce57b34SPawel Dziepak 		}
46*5945c55aSPawel Dziepak 	}
47*5945c55aSPawel Dziepak 
48*5945c55aSPawel Dziepak 	return fReply.SetTo(rpl);
49*5945c55aSPawel Dziepak }
50*5945c55aSPawel Dziepak 
51*5945c55aSPawel Dziepak 
52*5945c55aSPawel Dziepak status_t
53*5945c55aSPawel Dziepak Request::_SendTCP()
54*5945c55aSPawel Dziepak {
55*5945c55aSPawel Dziepak 	RPC::Reply *rpl;
56*5945c55aSPawel Dziepak 	RPC::Request *rpc;
57*5945c55aSPawel Dziepak 
58*5945c55aSPawel Dziepak 	status_t result;
59*5945c55aSPawel Dziepak 	int attempts = 0;
60*5945c55aSPawel Dziepak 	do {
61*5945c55aSPawel Dziepak 		result = fServer->SendCallAsync(fBuilder.Request(), &rpl, &rpc);
62*5945c55aSPawel Dziepak 		if (result == B_NO_MEMORY)
63*5945c55aSPawel Dziepak 			return result;
64*5945c55aSPawel Dziepak 		else if (result != B_OK) {
65*5945c55aSPawel Dziepak 			fServer->Repair();
66*5945c55aSPawel Dziepak 			continue;
67*5945c55aSPawel Dziepak 		}
68*5945c55aSPawel Dziepak 
69*5945c55aSPawel Dziepak 		result = fServer->WaitCall(rpc);
70*5945c55aSPawel Dziepak 		if (result != B_OK) {
71*5945c55aSPawel Dziepak 			fServer->CancelCall(rpc);
72*5945c55aSPawel Dziepak 			delete rpc;
73*5945c55aSPawel Dziepak 
74*5945c55aSPawel Dziepak 			fServer->Repair();
75*5945c55aSPawel Dziepak 		}
76*5945c55aSPawel Dziepak 	} while (result != B_OK && attempts++ < kRetryLimit);
773ce57b34SPawel Dziepak 
7801d6381dSPawel Dziepak 	return fReply.SetTo(rpl);
7901d6381dSPawel Dziepak }
8001d6381dSPawel Dziepak 
8101d6381dSPawel Dziepak 
8201d6381dSPawel Dziepak void
8301d6381dSPawel Dziepak Request::Reset()
8401d6381dSPawel Dziepak {
8501d6381dSPawel Dziepak 	fBuilder.Reset();
8601d6381dSPawel Dziepak 	fReply.Reset();
8701d6381dSPawel Dziepak }
8801d6381dSPawel Dziepak 
89