From 3ce57b347fe923dde6bcdba518a1ec479d43e84b Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Mon, 11 Jun 2012 20:24:32 +0200 Subject: [PATCH] nfs4: Make RPC calls asynchronous --- .../kernel/file_systems/nfs4/RPCServer.cpp | 40 ++++++++++++------- .../kernel/file_systems/nfs4/RPCServer.h | 22 ++++++++++ .../kernel/file_systems/nfs4/Request.cpp | 18 ++++++++- .../kernel/file_systems/nfs4/Request.h | 2 + 4 files changed, 67 insertions(+), 15 deletions(-) diff --git a/src/add-ons/kernel/file_systems/nfs4/RPCServer.cpp b/src/add-ons/kernel/file_systems/nfs4/RPCServer.cpp index fed27887e6..5d62e265e2 100644 --- a/src/add-ons/kernel/file_systems/nfs4/RPCServer.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/RPCServer.cpp @@ -119,8 +119,26 @@ Server::_StartListening() status_t Server::SendCall(Call* call, Reply** reply) { - status_t result; + Request* req; + status_t result = SendCallAsync(call, reply, &req); + if (result != B_OK) + return result; + result = WaitCall(req); + if (result != B_OK) { + CancelCall(req); + delete req; + return result; + } + + delete req; + return B_OK; +} + + +status_t +Server::SendCallAsync(Call* call, Reply** reply, Request** request) +{ if (fThreadError != B_OK) return fThreadError; @@ -137,21 +155,15 @@ Server::SendCall(Call* call, Reply** reply) fRequests.AddRequest(req); XDR::WriteStream& stream = call->Stream(); - result = fConnection->Send(stream.Buffer(), stream.Size()); - if (result != B_OK) - goto out_cancel; + status_t result = fConnection->Send(stream.Buffer(), stream.Size()); + if (result != B_OK) { + fRequests.FindRequest(xid); + delete req; + return result; + } - result = req->fEvent.Wait(B_RELATIVE_TIMEOUT, kWaitTime); - if (result != B_OK) - goto out_cancel; - - delete req; + *request = req; return B_OK; - -out_cancel: - fRequests.FindRequest(xid); - delete req; - return result; } diff --git a/src/add-ons/kernel/file_systems/nfs4/RPCServer.h b/src/add-ons/kernel/file_systems/nfs4/RPCServer.h index 13cf8b2256..bd10454ccc 100644 --- a/src/add-ons/kernel/file_systems/nfs4/RPCServer.h +++ b/src/add-ons/kernel/file_systems/nfs4/RPCServer.h @@ -50,6 +50,12 @@ public: status_t SendCall(Call* call, Reply** reply); + status_t SendCallAsync(Call* call, Reply** reply, + Request** request); + inline status_t WaitCall(Request* request, + bigtime_t time = kWaitTime); + inline status_t CancelCall(Request* request); + status_t Repair(); inline const ServerAddress& ID() const; @@ -75,6 +81,22 @@ private: static const bigtime_t kWaitTime = 1000000; }; + +inline status_t +Server::WaitCall(Request* request, bigtime_t time) +{ + return request->fEvent.Wait(B_RELATIVE_TIMEOUT, time); +} + + +inline status_t +Server::CancelCall(Request* request) +{ + fRequests.FindRequest(request->fXID); + return B_OK; +} + + inline const ServerAddress& Server::ID() const { diff --git a/src/add-ons/kernel/file_systems/nfs4/Request.cpp b/src/add-ons/kernel/file_systems/nfs4/Request.cpp index 83760ba01f..65efca366d 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Request.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Request.cpp @@ -12,12 +12,28 @@ status_t Request::Send() +{ + return _TrySend(); +} + + +status_t +Request::_TrySend() { RPC::Reply *rpl; - status_t result = fServer->SendCall(fBuilder.Request(), &rpl); + RPC::Request *rpc; + + status_t result = fServer->SendCallAsync(fBuilder.Request(), &rpl, &rpc); if (result != B_OK) return result; + result = fServer->WaitCall(rpc); + if (result != B_OK) { + fServer->CancelCall(rpc); + delete rpc; + return result; + } + return fReply.SetTo(rpl); } diff --git a/src/add-ons/kernel/file_systems/nfs4/Request.h b/src/add-ons/kernel/file_systems/nfs4/Request.h index 3db4e42e10..60dc99b8f5 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Request.h +++ b/src/add-ons/kernel/file_systems/nfs4/Request.h @@ -25,6 +25,8 @@ public: void Reset(); private: + status_t _TrySend(); + RPC::Server* fServer; RequestBuilder fBuilder;