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 16 status_t 17 Request::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 28 status_t 29 Request::_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 91 status_t 92 Request::_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 153 void 154 Request::Reset() 155 { 156 fBuilder.Reset(); 157 fReply.Reset(); 158 } 159 160