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 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 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 41060a4636SPawel Dziepak int retryLimit = 0; 42060a4636SPawel Dziepak bool hard = true; 43060a4636SPawel Dziepak if (fFileSystem != NULL) { 44060a4636SPawel Dziepak retryLimit = fFileSystem->GetConfiguration().fRetryLimit; 45060a4636SPawel Dziepak hard = fFileSystem->GetConfiguration().fHard; 46060a4636SPawel Dziepak } 47060a4636SPawel Dziepak 483ce57b34SPawel Dziepak result = fServer->WaitCall(rpc); 493ce57b34SPawel Dziepak if (result != B_OK) { 505945c55aSPawel Dziepak int attempts = 1; 51060a4636SPawel Dziepak while (result != B_OK && (hard || attempts++ < retryLimit)) { 525945c55aSPawel Dziepak result = fServer->ResendCallAsync(fBuilder.Request(), rpc); 53be4c74eaSPawel Dziepak if (result != B_OK) { 54be4c74eaSPawel Dziepak if (cookie != NULL) 55be4c74eaSPawel Dziepak cookie->UnregisterRequest(rpc); 560792abe0SPawel Dziepak return result; 57be4c74eaSPawel Dziepak } 585945c55aSPawel Dziepak 590792abe0SPawel Dziepak result = fServer->WaitCall(rpc); 600792abe0SPawel Dziepak } 610792abe0SPawel Dziepak 620792abe0SPawel Dziepak if (result != B_OK) { 63be4c74eaSPawel Dziepak if (cookie != NULL) 64be4c74eaSPawel Dziepak cookie->UnregisterRequest(rpc); 653ce57b34SPawel Dziepak fServer->CancelCall(rpc); 663ce57b34SPawel Dziepak delete rpc; 673ce57b34SPawel Dziepak return result; 683ce57b34SPawel Dziepak } 695945c55aSPawel Dziepak } 705945c55aSPawel Dziepak 71be4c74eaSPawel Dziepak if (cookie != NULL) 72be4c74eaSPawel Dziepak cookie->UnregisterRequest(rpc); 73be4c74eaSPawel Dziepak 74be4c74eaSPawel Dziepak if (rpc->fError != B_OK) { 75be4c74eaSPawel Dziepak delete rpl; 76be4c74eaSPawel Dziepak result = rpc->fError; 77be4c74eaSPawel Dziepak delete rpc; 78be4c74eaSPawel Dziepak return result; 79be4c74eaSPawel Dziepak } else { 80be4c74eaSPawel Dziepak fReply.SetTo(rpl); 81be4c74eaSPawel Dziepak delete rpc; 82be4c74eaSPawel Dziepak return B_OK; 83be4c74eaSPawel Dziepak } 845945c55aSPawel Dziepak } 855945c55aSPawel Dziepak 865945c55aSPawel Dziepak 875945c55aSPawel Dziepak status_t 88be4c74eaSPawel Dziepak Request::_SendTCP(Cookie* cookie) 895945c55aSPawel Dziepak { 90be4c74eaSPawel Dziepak RPC::Reply* rpl = NULL; 915945c55aSPawel Dziepak RPC::Request* rpc; 925945c55aSPawel Dziepak 935945c55aSPawel Dziepak status_t result; 945945c55aSPawel Dziepak int attempts = 0; 95060a4636SPawel Dziepak 96060a4636SPawel Dziepak int retryLimit = 0; 97060a4636SPawel Dziepak bool hard = true; 98060a4636SPawel Dziepak 99060a4636SPawel Dziepak if (fFileSystem != NULL) { 100060a4636SPawel Dziepak retryLimit = fFileSystem->GetConfiguration().fRetryLimit; 101060a4636SPawel Dziepak hard = fFileSystem->GetConfiguration().fHard; 102060a4636SPawel Dziepak } 103060a4636SPawel Dziepak 1045945c55aSPawel Dziepak do { 1055945c55aSPawel Dziepak result = fServer->SendCallAsync(fBuilder.Request(), &rpl, &rpc); 1065945c55aSPawel Dziepak if (result == B_NO_MEMORY) 1075945c55aSPawel Dziepak return result; 1085945c55aSPawel Dziepak else if (result != B_OK) { 1095945c55aSPawel Dziepak fServer->Repair(); 1105945c55aSPawel Dziepak continue; 1115945c55aSPawel Dziepak } 1125945c55aSPawel Dziepak 113be4c74eaSPawel Dziepak if (cookie != NULL) 114be4c74eaSPawel Dziepak cookie->RegisterRequest(rpc); 115be4c74eaSPawel Dziepak 1165945c55aSPawel Dziepak result = fServer->WaitCall(rpc); 1175945c55aSPawel Dziepak if (result != B_OK) { 118be4c74eaSPawel Dziepak if (cookie != NULL) 119be4c74eaSPawel Dziepak cookie->UnregisterRequest(rpc); 120be4c74eaSPawel Dziepak 1215945c55aSPawel Dziepak fServer->CancelCall(rpc); 1225945c55aSPawel Dziepak delete rpc; 1235945c55aSPawel Dziepak 1245945c55aSPawel Dziepak fServer->Repair(); 1255945c55aSPawel Dziepak } 126060a4636SPawel Dziepak } while (result != B_OK && (hard || attempts++ < retryLimit)); 1273ce57b34SPawel Dziepak 128*e8ef557aSPawel Dziepak if (result != B_OK) 129*e8ef557aSPawel Dziepak return result; 130*e8ef557aSPawel Dziepak 131be4c74eaSPawel Dziepak if (cookie != NULL) 132be4c74eaSPawel Dziepak cookie->UnregisterRequest(rpc); 133be4c74eaSPawel Dziepak 134be4c74eaSPawel Dziepak if (rpc->fError != B_OK) { 135be4c74eaSPawel Dziepak delete rpl; 136be4c74eaSPawel Dziepak result = rpc->fError; 137be4c74eaSPawel Dziepak delete rpc; 138be4c74eaSPawel Dziepak return result; 139*e8ef557aSPawel Dziepak } 140*e8ef557aSPawel Dziepak 141be4c74eaSPawel Dziepak fReply.SetTo(rpl); 142be4c74eaSPawel Dziepak delete rpc; 143be4c74eaSPawel Dziepak return B_OK; 14401d6381dSPawel Dziepak } 14501d6381dSPawel Dziepak 14601d6381dSPawel Dziepak 14701d6381dSPawel Dziepak void 14801d6381dSPawel Dziepak Request::Reset() 14901d6381dSPawel Dziepak { 15001d6381dSPawel Dziepak fBuilder.Reset(); 15101d6381dSPawel Dziepak fReply.Reset(); 15201d6381dSPawel Dziepak } 15301d6381dSPawel Dziepak 154