nfs4: Add locking to protect a ConditionVariable
* Ensure that after RPC::Server::SendCallAsync() returns, its client can't delete RPC::Request::fEvent while fEvent.NotifyAll() is still in progress in the notifying thread. * Fixes #19764. Change-Id: I516fe5a1c4e0f6939c62d6d5e3b91771ab12223c Reviewed-on: https://review.haiku-os.org/c/haiku/+/9709 Tested-by: Commit checker robot <[email protected]> Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
@@ -21,6 +21,19 @@
|
||||
using namespace RPC;
|
||||
|
||||
|
||||
Request::Request()
|
||||
{
|
||||
mutex_init(&fEventLock, "nfs4 Request");
|
||||
}
|
||||
|
||||
|
||||
Request::~Request()
|
||||
{
|
||||
mutex_lock(&fEventLock);
|
||||
mutex_destroy(&fEventLock);
|
||||
}
|
||||
|
||||
|
||||
RequestManager::RequestManager()
|
||||
:
|
||||
fQueueHead(NULL),
|
||||
@@ -203,7 +216,10 @@ Server::WakeCall(Request* request)
|
||||
request->fError = B_IO_ERROR;
|
||||
*request->fReply = NULL;
|
||||
request->fDone = true;
|
||||
mutex_lock(&request->fEventLock);
|
||||
// don't let the sending thread free request->fEvent until NotifyAll returns
|
||||
request->fEvent.NotifyAll();
|
||||
mutex_unlock(&request->fEventLock);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
@@ -294,7 +310,10 @@ Server::_Listener()
|
||||
if (req != NULL) {
|
||||
*req->fReply = reply;
|
||||
req->fDone = true;
|
||||
mutex_lock(&req->fEventLock);
|
||||
// don't let the sending thread free req->fEvent until NotifyAll returns
|
||||
req->fEvent.NotifyAll();
|
||||
mutex_unlock(&req->fEventLock);
|
||||
} else
|
||||
delete reply;
|
||||
}
|
||||
|
||||
@@ -21,8 +21,12 @@
|
||||
namespace RPC {
|
||||
|
||||
struct Request {
|
||||
Request();
|
||||
~Request();
|
||||
|
||||
uint32 fXID;
|
||||
ConditionVariable fEvent;
|
||||
mutex fEventLock;
|
||||
|
||||
bool fDone;
|
||||
Reply** fReply;
|
||||
|
||||
Reference in New Issue
Block a user