1/* 2 * Copyright 2012 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Paweł Dziepak, pdziepak@quarnos.org 7 */ 8 9 10#include "Request.h" 11 12#include "FileSystem.h" 13#include "Inode.h" 14 15 16status_t 17Request::Send(Cookie* cookie) 18{ 19 switch (fServer->ID().fProtocol) { 20 case IPPROTO_UDP: return _SendUDP(cookie); 21 case IPPROTO_TCP: return _SendTCP(cookie); 22 } 23 24 return B_BAD_VALUE; 25} 26 27 28status_t 29Request::_SendUDP(Cookie* cookie) 30{ 31 RPC::Reply* rpl = NULL; 32 RPC::Request* rpc; 33 34 status_t result = fServer->SendCallAsync(fBuilder.Request(), &rpl, &rpc); 35 if (result != B_OK) 36 return result; 37 38 if (cookie != NULL) 39 cookie->RegisterRequest(rpc); 40 41 int requestTimeout = sSecToBigTime(60); 42 int retryLimit = 0; 43 bool hard = true; 44 45 if (fFileSystem != NULL) { 46 requestTimeout = fFileSystem->GetConfiguration().fRequestTimeout; 47 retryLimit = fFileSystem->GetConfiguration().fRetryLimit; 48 hard = fFileSystem->GetConfiguration().fHard; 49 } 50 51 result = fServer->WaitCall(rpc, requestTimeout); 52 if (result != B_OK) { 53 int attempts = 1; 54 while (result != B_OK && (hard || attempts++ < retryLimit)) { 55 result = fServer->ResendCallAsync(fBuilder.Request(), rpc); 56 if (result != B_OK) { 57 if (cookie != NULL) 58 cookie->UnregisterRequest(rpc); 59 delete rpc; 60 return result; 61 } 62 63 result = fServer->WaitCall(rpc, requestTimeout); 64 } 65 66 if (result != B_OK) { 67 if (cookie != NULL) 68 cookie->UnregisterRequest(rpc); 69 fServer->CancelCall(rpc); 70 delete rpc; 71 return result; 72 } 73 } 74 75 if (cookie != NULL) 76 cookie->UnregisterRequest(rpc); 77 78 if (rpc->fError != B_OK) { 79 delete rpl; 80 result = rpc->fError; 81 delete rpc; 82 return result; 83 } else { 84 fReply.SetTo(rpl); 85 delete rpc; 86 return B_OK; 87 } 88} 89 90 91status_t 92Request::_SendTCP(Cookie* cookie) 93{ 94 RPC::Reply* rpl = NULL; 95 RPC::Request* rpc; 96 97 status_t result; 98 int attempts = 0; 99 100 int requestTimeout = sSecToBigTime(60); 101 int retryLimit = 0; 102 bool hard = true; 103 104 if (fFileSystem != NULL) { 105 requestTimeout = fFileSystem->GetConfiguration().fRequestTimeout; 106 retryLimit = fFileSystem->GetConfiguration().fRetryLimit; 107 hard = fFileSystem->GetConfiguration().fHard; 108 } 109 110 do { 111 result = fServer->SendCallAsync(fBuilder.Request(), &rpl, &rpc); 112 if (result == B_NO_MEMORY) 113 return result; 114 else if (result != B_OK) { 115 fServer->Repair(); 116 continue; 117 } 118 119 if (cookie != NULL) 120 cookie->RegisterRequest(rpc); 121 122 result = fServer->WaitCall(rpc, requestTimeout); 123 if (result != B_OK) { 124 if (cookie != NULL) 125 cookie->UnregisterRequest(rpc); 126 127 fServer->CancelCall(rpc); 128 delete rpc; 129 130 fServer->Repair(); 131 } 132 } while (result != B_OK && (hard || attempts++ < retryLimit)); 133 134 if (result != B_OK) 135 return result; 136 137 if (cookie != NULL) 138 cookie->UnregisterRequest(rpc); 139 140 if (rpc->fError != B_OK) { 141 delete rpl; 142 result = rpc->fError; 143 delete rpc; 144 return result; 145 } 146 147 fReply.SetTo(rpl); 148 delete rpc; 149 return B_OK; 150} 151 152 153void 154Request::Reset() 155{ 156 fBuilder.Reset(); 157 fReply.Reset(); 158} 159 160