diff --git a/src/rsrv/camessage.c b/src/rsrv/camessage.c index 9a57091a1..1e6e1d908 100644 --- a/src/rsrv/camessage.c +++ b/src/rsrv/camessage.c @@ -1392,6 +1392,7 @@ LOCAL void write_notify_call_back(putNotify *ppn) */ epicsMutexMustLock(pclient->putNotifyLock); ellAdd(&pclient->putNotifyQue, &pciu->pPutNotify->node); + pciu->pPutNotify->onExtraLaborQueue = TRUE; epicsMutexUnlock(pclient->putNotifyLock); /* @@ -1427,6 +1428,7 @@ void write_notify_reply(void *pArg) */ epicsMutexMustLock(pClient->putNotifyLock); ppnb = (RSRVPUTNOTIFY *)ellGet(&pClient->putNotifyQue); + ppnb->onExtraLaborQueue = FALSE; epicsMutexUnlock(pClient->putNotifyLock); /* * break to loop exit @@ -1581,6 +1583,7 @@ LOCAL int write_notify_action ( caHdrLargeArray *mp, void *pPayload, } pciu->pPutNotify->busy = TRUE; + pciu->pPutNotify->onExtraLaborQueue = FALSE; pciu->pPutNotify->msg = *mp; pciu->pPutNotify->dbPutNotify.nRequest = mp->m_count; #ifdef CONVERSION_REQUIRED @@ -1737,9 +1740,14 @@ LOCAL int clear_channel_reply ( caHdrLargeArray *mp, void *pPayload, struct clie * if a put notify is outstanding then cancel it */ if(pciu->pPutNotify){ - if(pciu->pPutNotify->busy){ - dbNotifyCancel(&pciu->pPutNotify->dbPutNotify); - } + if(pciu->pPutNotify->busy){ + dbNotifyCancel ( &pciu->pPutNotify->dbPutNotify ); + } + epicsMutexMustLock ( client->putNotifyLock ); + if ( pciu->pPutNotify->onExtraLaborQueue ) { + ellDelete ( &client->putNotifyQue, &pciu->pPutNotify->node ); + } + epicsMutexUnlock ( client->putNotifyLock ); } while (TRUE){ diff --git a/src/rsrv/caservertask.c b/src/rsrv/caservertask.c index 2ac131178..d5587abc3 100644 --- a/src/rsrv/caservertask.c +++ b/src/rsrv/caservertask.c @@ -560,27 +560,33 @@ void destroy_tcp_client ( struct client *client ) errlogPrintf ( "CAS: Connection %d Terminated\n", client->sock ); } - if ( client->evuser ) { - db_event_flow_ctrl_mode_off ( client->evuser ); - } + /* + * turn off extra labor callbacks from the event thread + */ + status = db_add_extra_labor_event ( client->evuser, NULL, NULL ); + assert ( ! status ); - while ( TRUE ){ + /* + * wait for extra labor in progress to comple + */ + status = db_flush_extra_labor_event ( client->evuser ); + assert ( ! status ); + + /* + * wait for any put notify in progress to comple + */ + status = db_flush_extra_labor_event(client->evuser); + assert ( ! status ); + + while ( TRUE ) { epicsMutexMustLock ( client->addrqLock ); - pciu = (struct channel_in_use *) ellGet ( &client->addrq ); + pciu = (struct channel_in_use *) ellGet ( & client->addrq ); epicsMutexUnlock ( client->addrqLock ); + if ( ! pciu ) { break; } - /* - * put notify in progress needs to be deleted - */ - if ( pciu->pPutNotify ) { - if ( pciu->pPutNotify->busy ) { - dbNotifyCancel ( &pciu->pPutNotify->dbPutNotify ); - } - } - while ( TRUE ) { /* * AS state change could be using this list @@ -598,10 +604,11 @@ void destroy_tcp_client ( struct client *client ) } freeListFree (rsrvEventFreeList, pevext); } - status = db_flush_extra_labor_event (client->evuser); - assert (status==DB_EVENT_OK); if (pciu->pPutNotify) { - free(pciu->pPutNotify); + if ( pciu->pPutNotify->busy ) { + dbNotifyCancel ( &pciu->pPutNotify->dbPutNotify ); + } + free ( pciu->pPutNotify ); } LOCK_CLIENTQ; status = bucketRemoveItemUnsignedId ( pCaBucket, &pciu->sid); diff --git a/src/rsrv/server.h b/src/rsrv/server.h index c2da22717..f2af5dba6 100644 --- a/src/rsrv/server.h +++ b/src/rsrv/server.h @@ -118,7 +118,8 @@ typedef struct rsrv_put_notify { putNotify dbPutNotify; caHdrLargeArray msg; unsigned valueSize; /* size of block pointed to by dbPutNotify */ - int busy; /* put notify in progress */ + char busy; /* put notify in progress */ + char onExtraLaborQueue; } RSRVPUTNOTIFY;