mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 16:56:45 +08:00
Fix segfault in EOWNERDEAD handling - remove incorrect ref count manipulation
Root cause: The previous code incorrectly called shm_->sub_ref() when handling EOWNERDEAD, which could cause the shared memory to be freed prematurely while the mutex pointer was still in use, leading to segmentation fault. Fix: Remove the shm_->sub_ref() call. When EOWNERDEAD is returned, it means we have successfully acquired the lock. We only need to call pthread_mutex_consistent() to make the mutex usable again, then return success. The shared memory reference count should not be modified in this path. This fixes the segfault in MutexTest.TryLockExceptionSafety on FreeBSD 15.
This commit is contained in:
parent
a82e3faf63
commit
47fa303455
@ -206,19 +206,15 @@ public:
|
||||
case ETIMEDOUT:
|
||||
return false;
|
||||
case EOWNERDEAD: {
|
||||
if (shm_->ref() > 1) {
|
||||
shm_->sub_ref();
|
||||
}
|
||||
// EOWNERDEAD means we have successfully acquired the lock,
|
||||
// but the previous owner died. We need to make it consistent.
|
||||
int eno2 = ::pthread_mutex_consistent(mutex_);
|
||||
if (eno2 != 0) {
|
||||
ipc::error("fail pthread_mutex_lock[%d], pthread_mutex_consistent[%d]\n", eno, eno2);
|
||||
return false;
|
||||
}
|
||||
// EOWNERDEAD means we have successfully acquired the lock,
|
||||
// but the previous owner died. After calling pthread_mutex_consistent(),
|
||||
// the mutex is now in a consistent state and we hold the lock.
|
||||
// We should return success here, not unlock and retry.
|
||||
// This avoids issues with FreeBSD's robust mutex list management.
|
||||
// After calling pthread_mutex_consistent(), the mutex is now in a
|
||||
// consistent state and we hold the lock. Return success.
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
@ -238,15 +234,15 @@ public:
|
||||
case ETIMEDOUT:
|
||||
return false;
|
||||
case EOWNERDEAD: {
|
||||
if (shm_->ref() > 1) {
|
||||
shm_->sub_ref();
|
||||
}
|
||||
// EOWNERDEAD means we have successfully acquired the lock,
|
||||
// but the previous owner died. We need to make it consistent.
|
||||
int eno2 = ::pthread_mutex_consistent(mutex_);
|
||||
if (eno2 != 0) {
|
||||
ipc::error("fail pthread_mutex_timedlock[%d], pthread_mutex_consistent[%d]\n", eno, eno2);
|
||||
throw std::system_error{eno2, std::system_category()};
|
||||
}
|
||||
// Successfully acquired the lock after making it consistent
|
||||
// After calling pthread_mutex_consistent(), the mutex is now in a
|
||||
// consistent state and we hold the lock. Return success.
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user