@@ -150,21 +150,19 @@ class mutex {
150150
151151 void close () noexcept {
152152 if ((ref_ != nullptr ) && (shm_ != nullptr ) && (mutex_ != nullptr )) {
153- // Try to unlock the mutex before destroying it.
154- // This is important for robust mutexes on FreeBSD, which maintain
155- // a per-thread robust list. If we destroy a mutex while it's in
156- // the robust list (even if not locked), FreeBSD may encounter
157- // dangling pointers later, leading to segfaults.
158- // We ignore any errors from unlock() since:
159- // 1. If we don't hold the lock, EPERM is expected and harmless
160- // 2. If the mutex is already unlocked, this is a no-op
161- // 3. If there's an error, we still want to proceed with cleanup
162- ::pthread_mutex_unlock (mutex_);
163-
164153 if (shm_->name () != nullptr ) {
165154 release_mutex (shm_->name (), [this ] {
166155 auto self_ref = ref_->fetch_sub (1 , std::memory_order_relaxed);
167156 if ((shm_->ref () <= 1 ) && (self_ref <= 1 )) {
157+ // Before destroying the mutex, try to unlock it.
158+ // This is important for robust mutexes on FreeBSD, which maintain
159+ // a per-thread robust list. If we destroy a mutex while it's locked
160+ // or still in the robust list, FreeBSD may encounter dangling pointers
161+ // later, leading to segfaults.
162+ // Only unlock here (when we're the last reference) to avoid
163+ // interfering with other threads that might be using the mutex.
164+ ::pthread_mutex_unlock (mutex_);
165+
168166 int eno;
169167 if ((eno = ::pthread_mutex_destroy (mutex_)) != 0 ) {
170168 ipc::error (" fail pthread_mutex_destroy[%d]\n " , eno);
@@ -182,11 +180,11 @@ class mutex {
182180
183181 void clear () noexcept {
184182 if ((shm_ != nullptr ) && (mutex_ != nullptr )) {
185- // Try to unlock before destroying, same reasoning as in close()
186- ::pthread_mutex_unlock (mutex_);
187-
188183 if (shm_->name () != nullptr ) {
189184 release_mutex (shm_->name (), [this ] {
185+ // Unlock before destroying, same reasoning as in close()
186+ ::pthread_mutex_unlock (mutex_);
187+
190188 int eno;
191189 if ((eno = ::pthread_mutex_destroy (mutex_)) != 0 ) {
192190 ipc::error (" fail pthread_mutex_destroy[%d]\n " , eno);
0 commit comments