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