nfs4: Make RPC calls asynchronous
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ public:
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
status_t _TrySend();
|
||||
|
||||
RPC::Server* fServer;
|
||||
|
||||
RequestBuilder fBuilder;
|
||||
|
||||
Reference in New Issue
Block a user