diff options
-rwxr-xr-x | srUtils.c | 30 | ||||
-rwxr-xr-x | srUtils.h | 37 |
2 files changed, 66 insertions, 1 deletions
@@ -311,6 +311,36 @@ int getNumberDigits(long lNum) } +/* compute an absolute time timeout suitable for calls to pthread_cond_timedwait() + * rgerhards, 2008-01-14 + */ +rsRetVal +timeoutComp(struct timespec *pt, int iTimeout) +{ + assert(pt != NULL); + /* compute timeout */ + clock_gettime(CLOCK_REALTIME, pt); + pt->tv_nsec += (iTimeout % 1000) * 1000000; /* think INTEGER arithmetic! */ + if(pt->tv_nsec > 999999999) { /* overrun? */ + pt->tv_nsec -= 1000000000; + ++pt->tv_sec; + } + pt->tv_sec += iTimeout / 1000; + return RS_RET_OK; /* so far, this is static... */ +} + + +/* cancellation cleanup handler - frees provided mutex + * rgerhards, 2008-01-14 + */ +void +mutexCancelCleanup(void *arg) +{ + assert(arg != NULL); + d_pthread_mutex_unlock((pthread_mutex_t*) arg); +} + + /* * vi:set ai: */ @@ -61,10 +61,45 @@ unsigned char *srUtilStrDup(unsigned char *pOld, size_t len); * added 2007-07-17 by rgerhards */ int makeFileParentDirs(uchar *szFile, size_t lenFile, mode_t mode, uid_t uid, gid_t gid, int bFailOnChown); - int execProg(uchar *program, int wait, uchar *arg); void skipWhiteSpace(uchar **pp); rsRetVal genFileName(uchar **ppName, uchar *pDirName, size_t lenDirName, uchar *pFName, size_t lenFName, long lNum, int lNumDigits); int getNumberDigits(long lNum); +rsRetVal timeoutComp(struct timespec *pt, int iTimeout); +void mutexCancelCleanup(void *arg); + +/* mutex operations */ +/* some macros to cancel-safe lock a mutex (it will automatically be released + * when the thread is cancelled. This needs to be done as macros because + * pthread_cleanup_push sometimes is a macro that can not be used inside a function. + * It's a bit ugly, but works well... rgerhards, 2008-01-20 + */ +#define DEFVARS_mutex_cancelsafeLock int iCancelStateSave +#define mutex_cancelsafe_lock(mut) \ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &iCancelStateSave); \ + d_pthread_mutex_lock(mut); \ + pthread_cleanup_push(mutexCancelCleanup, mut); \ + pthread_setcancelstate(iCancelStateSave, NULL); +#define mutex_cancelsafe_unlock(mut) pthread_cleanup_pop(1) + +/* some useful constants */ +#define MUTEX_ALREADY_LOCKED 0 +#define LOCK_MUTEX 1 +#define DEFVARS_mutexProtection\ + int iCancelStateSave; \ + int bLockedOpIsLocked +#define BEGIN_MTX_PROTECTED_OPERATIONS(mut, bMustLock) \ + if(bMustLock == LOCK_MUTEX) { \ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &iCancelStateSave); \ + d_pthread_mutex_lock(mut); \ + bLockedOpIsLocked = 1; \ + } else { \ + bLockedOpIsLocked = 0; \ + } +#define END_MTX_PROTECTED_OPERATIONS(mut) \ + if(bLockedOpIsLocked) { \ + d_pthread_mutex_unlock(mut); \ + pthread_setcancelstate(iCancelStateSave, NULL); \ + } #endif |