diff --git a/src/db/dbCAC.h b/src/db/dbCAC.h index 5fdcc4450..595630327 100644 --- a/src/db/dbCAC.h +++ b/src/db/dbCAC.h @@ -72,7 +72,8 @@ public: dbSubscriptionIO ( dbServiceIO &, dbChannelIO &, struct dbAddr &, cacStateNotify &, unsigned type, unsigned long count, unsigned mask, cacChannel::ioid * ); void destroy (); - void channelDestroyException (); + void unsubscribe (); + void channelDeleteException (); void show ( unsigned level ) const; void * operator new ( size_t size ); void operator delete ( void *pCadaver, size_t size ); diff --git a/src/db/dbServiceIO.cpp b/src/db/dbServiceIO.cpp index 25be69de5..0eeb9f035 100644 --- a/src/db/dbServiceIO.cpp +++ b/src/db/dbServiceIO.cpp @@ -257,6 +257,9 @@ void dbServiceIO::destroyAllIO ( dbChannelIO & chan ) while ( ( pIO = chan.dbServicePrivateListOfIO::eventq.get() ) ) { this->ioTable.remove ( *pIO ); tmp.add ( *pIO ); + // this prevents a db event callback from coming + // through after the IO is deleted + pIO->unsubscribe (); } if ( chan.dbServicePrivateListOfIO::pBlocker ) { this->ioTable.remove ( *chan.dbServicePrivateListOfIO::pBlocker ); @@ -265,7 +268,7 @@ void dbServiceIO::destroyAllIO ( dbChannelIO & chan ) while ( ( pIO = tmp.get() ) ) { // If they call ioCancel() here it will be ignored // because the IO has been unregistered above - pIO->channelDestroyException (); + pIO->channelDeleteException (); pIO->destroy (); } if ( chan.dbServicePrivateListOfIO::pBlocker ) { diff --git a/src/db/dbSubscriptionIO.cpp b/src/db/dbSubscriptionIO.cpp index 94d36712e..23130d3c0 100644 --- a/src/db/dbSubscriptionIO.cpp +++ b/src/db/dbSubscriptionIO.cpp @@ -64,7 +64,16 @@ void dbSubscriptionIO::destroy () delete this; } -void dbSubscriptionIO::channelDestroyException () +// lock should be applied +void dbSubscriptionIO::unsubscribe () +{ + if ( this->es ) { + db_cancel_event ( this->es ); + this->es = 0; + } +} + +void dbSubscriptionIO::channelDeleteException () { this->notify.exception ( ECA_CHANDESTROY, this->chan.pName(), this->type, this->count );