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:
Jim906
2025-10-23 16:04:35 +00:00
committed by waddlesplash
parent 08e8099b4a
commit 780acc5dcf
2 changed files with 23 additions and 0 deletions
@@ -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;