void dbNotifyCancel(processNotify *ppn) { dbCommon *precord = dbChannelRecord(ppn->chan); notifyState state; notifyPvt *pnotifyPvt; dbScanLock(precord); epicsMutexMustLock(pnotifyGlobal->lock); ppn->status = notifyCanceled; pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; if (!pnotifyPvt || pnotifyPvt->state == notifyNotActive) { epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); return; } state = pnotifyPvt->state; switch (state) { case notifyUserCallbackRequested: case notifyRestartCallbackRequested: case notifyUserCallbackActive: /* Callback is scheduled or active, wait for it to complete */ pnotifyPvt->cancelWait = 1; epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); epicsEventWait(pnotifyPvt->cancelEvent); epicsMutexMustLock(pnotifyGlobal->lock); notifyCleanup(ppn); epicsMutexUnlock(pnotifyGlobal->lock); return; case notifyNotActive: break; case notifyWaitForRestart: assert(precord->ppn); assert(precord->ppn!=ppn); ellSafeDelete(&precord->ppnr->restartList,&ppn->restartNode); break; case notifyRestartInProgress: case notifyProcessInProgress: { /*Take all records out of wait list */ processNotifyRecord *ppnrWait; while ((ppnrWait = (processNotifyRecord *) ellFirst(&pnotifyPvt->waitList))) { ellSafeDelete(&pnotifyPvt->waitList, &ppnrWait->waitNode); restartCheck(ppnrWait); } } if (precord->ppn == ppn) restartCheck(precord->ppnr); break; default: printf("dbNotify: illegal state for notifyCallback\n"); } pnotifyPvt->state = notifyNotActive; notifyCleanup(ppn); epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); }
void epicsShareAPI dbNotifyCancel(putNotify *ppn) { dbCommon *precord = ppn->paddr->precord; putNotifyState state; putNotifyPvt *pputNotifyPvt; assert(precord); dbScanLock(precord); epicsMutexMustLock(pnotifyGlobal->lock); pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; if(!pputNotifyPvt || pputNotifyPvt->state==putNotifyNotActive) { epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); return; } state = pputNotifyPvt->state; /*If callback is scheduled or active wait for it to complete*/ if(state==putNotifyUserCallbackRequested || state==putNotifyRestartCallbackRequested || state==putNotifyUserCallbackActive) { pputNotifyPvt->cancelWait = 1; epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); epicsEventWait(pputNotifyPvt->cancelEvent); epicsMutexMustLock(pnotifyGlobal->lock); putNotifyCleanup(ppn); epicsMutexUnlock(pnotifyGlobal->lock); return; } switch(state) { case putNotifyNotActive: break; case putNotifyWaitForRestart: assert(precord->ppn); assert(precord->ppn!=ppn); ellSafeDelete(&precord->ppnr->restartList,&ppn->restartNode); break; case putNotifyRestartInProgress: case putNotifyPutInProgress: { /*Take all records out of wait list */ putNotifyRecord *ppnrWait; while((ppnrWait = (putNotifyRecord *)ellFirst(&pputNotifyPvt->waitList))){ ellSafeDelete(&pputNotifyPvt->waitList,&ppnrWait->waitNode); restartCheck(ppnrWait); } } if(precord->ppn==ppn) restartCheck(precord->ppnr); break; default: printf("dbNotify: illegal state for notifyCallback\n"); } pputNotifyPvt->state = putNotifyNotActive; putNotifyCleanup(ppn); epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); }
void dbNotifyCompletion(dbCommon *precord) { processNotify *ppn = precord->ppn; notifyPvt *pnotifyPvt; epicsMutexMustLock(pnotifyGlobal->lock); assert(ppn); assert(precord->ppnr); pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; if (pnotifyPvt->state != notifyRestartInProgress && pnotifyPvt->state != notifyProcessInProgress) { epicsMutexUnlock(pnotifyGlobal->lock); return; } ellSafeDelete(&pnotifyPvt->waitList, &precord->ppnr->waitNode); if ((ellCount(&pnotifyPvt->waitList) != 0)) { restartCheck(precord->ppnr); } else if (pnotifyPvt->state == notifyProcessInProgress) { pnotifyPvt->state = notifyUserCallbackRequested; restartCheck(precord->ppnr); callbackRequest(&pnotifyPvt->callback); } else if(pnotifyPvt->state == notifyRestartInProgress) { pnotifyPvt->state = notifyRestartCallbackRequested; callbackRequest(&pnotifyPvt->callback); } else { cantProceed("dbNotifyCompletion illegal state"); } epicsMutexUnlock(pnotifyGlobal->lock); }
static void restartCheck(processNotifyRecord *ppnr) { dbCommon *precord = ppnr->precord; processNotify *pfirst; notifyPvt *pnotifyPvt; assert(precord->ppn); pfirst = (processNotify *) ellFirst(&ppnr->restartList); if (!pfirst) { precord->ppn = 0; return; } pnotifyPvt = (notifyPvt *) pfirst->pnotifyPvt; assert(pnotifyPvt->state == notifyWaitForRestart); /* remove pfirst from restartList */ ellSafeDelete(&ppnr->restartList, &pfirst->restartNode); /*make pfirst owner of the record*/ precord->ppn = pfirst; /* request callback for pfirst */ pnotifyPvt->state = notifyRestartCallbackRequested; callbackRequest(&pnotifyPvt->callback); }