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 10*be4c74eaSPawel Dziepak #include "Inode.h" 1101d6381dSPawel Dziepak #include "Request.h" 1201d6381dSPawel Dziepak 1301d6381dSPawel Dziepak 1401d6381dSPawel Dziepak status_t 15*be4c74eaSPawel Dziepak Request::Send(Cookie* cookie) 1601d6381dSPawel Dziepak { 175945c55aSPawel Dziepak switch (fServer->ID().fProtocol) { 18*be4c74eaSPawel Dziepak case ProtocolUDP: return _SendUDP(cookie); 19*be4c74eaSPawel Dziepak case ProtocolTCP: return _SendTCP(cookie); 205945c55aSPawel Dziepak } 215945c55aSPawel Dziepak 225945c55aSPawel Dziepak return B_BAD_VALUE; 233ce57b34SPawel Dziepak } 243ce57b34SPawel Dziepak 253ce57b34SPawel Dziepak 263ce57b34SPawel Dziepak status_t 27*be4c74eaSPawel Dziepak Request::_SendUDP(Cookie* cookie) 283ce57b34SPawel Dziepak { 29*be4c74eaSPawel Dziepak RPC::Reply *rpl = NULL; 303ce57b34SPawel Dziepak RPC::Request *rpc; 313ce57b34SPawel Dziepak 323ce57b34SPawel Dziepak status_t result = fServer->SendCallAsync(fBuilder.Request(), &rpl, &rpc); 3301d6381dSPawel Dziepak if (result != B_OK) 3401d6381dSPawel Dziepak return result; 3501d6381dSPawel Dziepak 36*be4c74eaSPawel Dziepak if (cookie != NULL) 37*be4c74eaSPawel Dziepak cookie->RegisterRequest(rpc); 38*be4c74eaSPawel Dziepak 393ce57b34SPawel Dziepak result = fServer->WaitCall(rpc); 403ce57b34SPawel Dziepak if (result != B_OK) { 415945c55aSPawel Dziepak int attempts = 1; 420792abe0SPawel Dziepak while (result != B_OK && attempts++ < kRetryLimit) { 435945c55aSPawel Dziepak result = fServer->ResendCallAsync(fBuilder.Request(), rpc); 44*be4c74eaSPawel Dziepak if (result != B_OK) { 45*be4c74eaSPawel Dziepak if (cookie != NULL) 46*be4c74eaSPawel Dziepak cookie->UnregisterRequest(rpc); 470792abe0SPawel Dziepak return result; 48*be4c74eaSPawel Dziepak } 495945c55aSPawel Dziepak 500792abe0SPawel Dziepak result = fServer->WaitCall(rpc); 510792abe0SPawel Dziepak } 520792abe0SPawel Dziepak 530792abe0SPawel Dziepak if (result != B_OK) { 54*be4c74eaSPawel Dziepak if (cookie != NULL) 55*be4c74eaSPawel Dziepak cookie->UnregisterRequest(rpc); 563ce57b34SPawel Dziepak fServer->CancelCall(rpc); 573ce57b34SPawel Dziepak delete rpc; 583ce57b34SPawel Dziepak return result; 593ce57b34SPawel Dziepak } 605945c55aSPawel Dziepak } 615945c55aSPawel Dziepak 62*be4c74eaSPawel Dziepak if (cookie != NULL) 63*be4c74eaSPawel Dziepak cookie->UnregisterRequest(rpc); 64*be4c74eaSPawel Dziepak 65*be4c74eaSPawel Dziepak if (rpc->fError != B_OK) { 66*be4c74eaSPawel Dziepak delete rpl; 67*be4c74eaSPawel Dziepak result = rpc->fError; 68*be4c74eaSPawel Dziepak delete rpc; 69*be4c74eaSPawel Dziepak return result; 70*be4c74eaSPawel Dziepak } else { 71*be4c74eaSPawel Dziepak fReply.SetTo(rpl); 72*be4c74eaSPawel Dziepak delete rpc; 73*be4c74eaSPawel Dziepak return B_OK; 74*be4c74eaSPawel Dziepak } 755945c55aSPawel Dziepak } 765945c55aSPawel Dziepak 775945c55aSPawel Dziepak 785945c55aSPawel Dziepak status_t 79*be4c74eaSPawel Dziepak Request::_SendTCP(Cookie* cookie) 805945c55aSPawel Dziepak { 81*be4c74eaSPawel Dziepak RPC::Reply *rpl = NULL; 825945c55aSPawel Dziepak RPC::Request *rpc; 835945c55aSPawel Dziepak 845945c55aSPawel Dziepak status_t result; 855945c55aSPawel Dziepak int attempts = 0; 865945c55aSPawel Dziepak do { 875945c55aSPawel Dziepak result = fServer->SendCallAsync(fBuilder.Request(), &rpl, &rpc); 885945c55aSPawel Dziepak if (result == B_NO_MEMORY) 895945c55aSPawel Dziepak return result; 905945c55aSPawel Dziepak else if (result != B_OK) { 915945c55aSPawel Dziepak fServer->Repair(); 925945c55aSPawel Dziepak continue; 935945c55aSPawel Dziepak } 945945c55aSPawel Dziepak 95*be4c74eaSPawel Dziepak if (cookie != NULL) 96*be4c74eaSPawel Dziepak cookie->RegisterRequest(rpc); 97*be4c74eaSPawel Dziepak 985945c55aSPawel Dziepak result = fServer->WaitCall(rpc); 995945c55aSPawel Dziepak if (result != B_OK) { 100*be4c74eaSPawel Dziepak if (cookie != NULL) 101*be4c74eaSPawel Dziepak cookie->UnregisterRequest(rpc); 102*be4c74eaSPawel Dziepak 1035945c55aSPawel Dziepak fServer->CancelCall(rpc); 1045945c55aSPawel Dziepak delete rpc; 1055945c55aSPawel Dziepak 1065945c55aSPawel Dziepak fServer->Repair(); 1075945c55aSPawel Dziepak } 1085945c55aSPawel Dziepak } while (result != B_OK && attempts++ < kRetryLimit); 1093ce57b34SPawel Dziepak 110*be4c74eaSPawel Dziepak if (cookie != NULL) 111*be4c74eaSPawel Dziepak cookie->UnregisterRequest(rpc); 112*be4c74eaSPawel Dziepak 113*be4c74eaSPawel Dziepak if (rpc->fError != B_OK) { 114*be4c74eaSPawel Dziepak delete rpl; 115*be4c74eaSPawel Dziepak result = rpc->fError; 116*be4c74eaSPawel Dziepak delete rpc; 117*be4c74eaSPawel Dziepak return result; 118*be4c74eaSPawel Dziepak } else { 119*be4c74eaSPawel Dziepak fReply.SetTo(rpl); 120*be4c74eaSPawel Dziepak delete rpc; 121*be4c74eaSPawel Dziepak return B_OK; 122*be4c74eaSPawel Dziepak }; 12301d6381dSPawel Dziepak } 12401d6381dSPawel Dziepak 12501d6381dSPawel Dziepak 12601d6381dSPawel Dziepak void 12701d6381dSPawel Dziepak Request::Reset() 12801d6381dSPawel Dziepak { 12901d6381dSPawel Dziepak fBuilder.Reset(); 13001d6381dSPawel Dziepak fReply.Reset(); 13101d6381dSPawel Dziepak } 13201d6381dSPawel Dziepak 133