wtiCancelThrd(wti_t *pThis, const uchar *const cancelobj) { DEFiRet; ISOBJ_TYPE_assert(pThis, wti); if(wtiGetState(pThis)) { LogMsg(0, RS_RET_ERR, LOG_WARNING, "%s: need to do cooperative cancellation " "- some data may be lost, increase timeout?", cancelobj); /* we first try the cooperative "cancel" interface */ pthread_kill(pThis->thrdID, SIGTTIN); DBGPRINTF("sent SIGTTIN to worker thread %p, giving it a chance to terminate\n", (void *) pThis->thrdID); srSleep(0, 10000); } if(wtiGetState(pThis)) { LogMsg(0, RS_RET_ERR, LOG_WARNING, "%s: need to do hard cancellation", cancelobj); DBGPRINTF("cooperative worker termination failed, using cancellation...\n"); DBGOPRINT((obj_t*) pThis, "canceling worker thread\n"); pthread_cancel(pThis->thrdID); /* now wait until the thread terminates... */ while(wtiGetState(pThis)) { srSleep(0, 10000); } } RETiRet; }
/* Cancel the thread. If the thread is not running. But it is save and legal to * call wtiCancelThrd() in such situations. This function only returns when the * thread has terminated. Else we may get race conditions all over the code... * Note that when waiting for the thread to terminate, we do a busy wait, checking * progress every 10ms. It is very unlikely that we will ever cancel a thread * and, if so, it will only happen at the end of the rsyslog run. So doing this * kind of non-optimal wait is considered preferable over using condition variables. * rgerhards, 2008-02-26 */ rsRetVal wtiCancelThrd(wti_t *pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, wti); if(wtiGetState(pThis)) { /* we first try the cooperative "cancel" interface */ pthread_kill(pThis->thrdID, SIGTTIN); DBGPRINTF("sent SIGTTIN to worker thread 0x%x, giving it a chance to terminate\n", (unsigned) pThis->thrdID); srSleep(0, 10000); } if(wtiGetState(pThis)) { DBGPRINTF("cooperative worker termination failed, using cancellation...\n"); DBGOPRINT((obj_t*) pThis, "canceling worker thread\n"); pthread_cancel(pThis->thrdID); /* now wait until the thread terminates... */ while(wtiGetState(pThis)) { srSleep(0, 10000); } } RETiRet; }
/* advise all workers to start by interrupting them. That should unblock all srSleep() * calls. */ rsRetVal wtiWakeupThrd(wti_t *pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, wti); if(wtiGetState(pThis)) { /* we first try the cooperative "cancel" interface */ pthread_kill(pThis->thrdID, SIGTTIN); DBGPRINTF("sent SIGTTIN to worker thread %p\n", (void*) pThis->thrdID); } RETiRet; }
/* advise all workers to start by interrupting them. That should unblock all srSleep() * calls. */ rsRetVal wtiWakeupThrd(wti_t *pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, wti); if(wtiGetState(pThis)) { /* we first try the cooperative "cancel" interface */ pthread_kill(pThis->thrdID, SIGTTIN); dbgprintf("sent SIGTTIN to worker thread 0x%x\n", (unsigned) pThis->thrdID); } RETiRet; }