From 448da22f20b4893f605095015bcc7dd092ad1fe3 Mon Sep 17 00:00:00 2001 From: Justin Lewis Salmon Date: Fri, 26 Apr 2013 16:00:38 +0100 Subject: [PATCH] Use cleanup handler in mac-specific semaphore implementation to allow its condition variable to be unlocked on thread cancellation --- src/XrdSys/XrdSysPthread.cc | 23 +++++++++++++++++++---- src/XrdSys/XrdSysPthread.hh | 2 ++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/XrdSys/XrdSysPthread.cc b/src/XrdSys/XrdSysPthread.cc index 2ada1766175..752fafb18b7 100644 --- a/src/XrdSys/XrdSysPthread.cc +++ b/src/XrdSys/XrdSysPthread.cc @@ -220,10 +220,14 @@ void XrdSysSemaphore::Post() void XrdSysSemaphore::Wait() { -// Wait until the sempahore value is positive. This will not be starvation -// free is the OS implements an unfair mutex; +// Wait until the semaphore value is positive. This will not be starvation +// free if the OS implements an unfair mutex. +// Adding a cleanup handler to the stack here enables threads using this OSX +// semaphore to be canceled (which is rare). A scoped lock won't work here +// because OSX is broken and doesn't call destructors properly. // - XrdSysCondVarHelper scopedLock(&semVar); + semVar.Lock(); + pthread_cleanup_push(&XrdSysSemaphore::CleanUp, (void *) &semVar); if (semVal < 1 || semWait) while(semVal < 1) {semWait++; @@ -231,9 +235,20 @@ void XrdSysSemaphore::Wait() semWait--; } -// Decrement the semaphore value and return +// Decrement the semaphore value, unlock the underlying cond var and return // semVal--; + pthread_cleanup_pop(1); +} + +/******************************************************************************/ +/* C l e a n U p */ +/******************************************************************************/ + +void XrdSysSemaphore::CleanUp(void *semVar) +{ + XrdSysCondVar *sv = (XrdSysCondVar *) semVar; + sv->UnLock(); } #endif diff --git a/src/XrdSys/XrdSysPthread.hh b/src/XrdSys/XrdSysPthread.hh index 1a1338e9e68..5132530098d 100644 --- a/src/XrdSys/XrdSysPthread.hh +++ b/src/XrdSys/XrdSysPthread.hh @@ -311,6 +311,8 @@ public: void Wait(); +static void CleanUp(void *semVar); + XrdSysSemaphore(int semval=1,const char *cid=0) : semVar(0, cid) {semVal = semval; semWait = 0;} ~XrdSysSemaphore() {}