upgrade locking

This commit is contained in:
Jeff Hill
2001-03-07 16:35:39 +00:00
parent 35a62778b8
commit 9e2297bd78
4 changed files with 60 additions and 89 deletions

View File

@@ -29,6 +29,7 @@
#include "dbNotifyBlockerIL.h"
tsFreeList < dbChannelIO > dbChannelIO::freeList;
epicsMutex dbChannelIO::freeListMutex;
dbChannelIO::dbChannelIO ( cacChannelNotify &notify,
const dbAddr &addrIn, dbServiceIO &serviceIO ) :
@@ -45,16 +46,16 @@ void dbChannelIO::initiateConnect ()
dbChannelIO::~dbChannelIO ()
{
this->lock ();
dbAutoScanLock ( *this->addr.precord );
/*
* remove any subscriptions attached to this channel
*/
tsDLIterBD <dbSubscriptionIO> iter = this->eventq.firstIter ();
tsDLIterBD < dbSubscriptionIO > iter = this->eventq.firstIter ();
while ( iter.valid () ) {
tsDLIterBD <dbSubscriptionIO> next = iter;
next++;
iter->destroy ();
iter->cancel ();
iter = next;
}
@@ -65,8 +66,6 @@ dbChannelIO::~dbChannelIO ()
if ( this->pGetCallbackCache ) {
delete [] this->pGetCallbackCache;
}
this->unlock ();
}
int dbChannelIO::read ( unsigned type, unsigned long count, void *pValue )
@@ -97,29 +96,29 @@ int dbChannelIO::read ( unsigned type, unsigned long count, cacNotify &notify )
return ECA_BADCOUNT;
}
this->lock ();
if ( this->getCallbackCacheSize < size) {
if ( this->pGetCallbackCache ) {
delete [] this->pGetCallbackCache;
{
dbAutoScanLock ( *this->addr.precord );
if ( this->getCallbackCacheSize < size) {
if ( this->pGetCallbackCache ) {
delete [] this->pGetCallbackCache;
}
this->pGetCallbackCache = new char [size];
if ( ! this->pGetCallbackCache ) {
this->getCallbackCacheSize = 0ul;
return ECA_ALLOCMEM;
}
this->getCallbackCacheSize = size;
}
this->pGetCallbackCache = new char [size];
if ( ! this->pGetCallbackCache ) {
this->getCallbackCacheSize = 0ul;
this->unlock ();
return ECA_ALLOCMEM;
int status = db_get_field ( &this->addr, static_cast <int> ( type ),
this->pGetCallbackCache, static_cast <int> ( count ), 0);
if ( status ) {
notify.exceptionNotify ( *this, ECA_GETFAIL,
"db_get_field () completed unsuccessfuly" );
}
else {
notify.completionNotify ( *this, type, count, this->pGetCallbackCache );
}
this->getCallbackCacheSize = size;
}
int status = db_get_field ( &this->addr, static_cast <int> ( type ),
this->pGetCallbackCache, static_cast <int> ( count ), 0);
if ( status ) {
notify.exceptionNotify ( *this, ECA_GETFAIL,
"db_get_field () completed unsuccessfuly" );
}
else {
notify.completionNotify ( *this, type, count, this->pGetCallbackCache );
}
this->unlock ();
notify.release ();
return ECA_NORMAL;
}
@@ -147,15 +146,13 @@ int dbChannelIO::write ( unsigned type, unsigned long count,
}
if ( ! this->pBlocker ) {
this->lock ();
dbAutoScanLock ( *this->addr.precord );
if ( ! this->pBlocker ) {
this->pBlocker = new dbPutNotifyBlocker ( *this );
if ( ! this->pBlocker ) {
this->unlock ();
return ECA_ALLOCMEM;
}
}
this->unlock ();
}
// must release the lock here so that this can block
@@ -179,22 +176,14 @@ int dbChannelIO::subscribe ( unsigned type, unsigned long count,
pReturnIO = pIO;
}
else {
pIO->destroy ();
pIO->cancel ();
}
return status;
}
void dbChannelIO::lockOutstandingIO () const
{
}
void dbChannelIO::unlockOutstandingIO () const
{
}
void dbChannelIO::show ( unsigned level ) const
{
this->lock ();
dbAutoScanLock ( *this->addr.precord );
printf ("channel at %p attached to local database record %s\n",
static_cast <const void *> ( this ), this->addr.precord->name );
@@ -216,5 +205,4 @@ void dbChannelIO::show ( unsigned level ) const
this->pBlocker->show ( level - 2u );
}
}
this->unlock ();
}

View File

@@ -34,11 +34,13 @@ inline void dbChannelIO::destroy ()
inline void * dbChannelIO::operator new ( size_t size )
{
epicsAutoMutex locker ( dbChannelIO::freeListMutex );
return dbChannelIO::freeList.allocate ( size );
}
inline void dbChannelIO::operator delete ( void *pCadaver, size_t size )
{
epicsAutoMutex locker ( dbChannelIO::freeListMutex );
dbChannelIO::freeList.release ( pCadaver, size );
}
@@ -58,16 +60,6 @@ inline void dbChannelIO::subscriptionUpdate ( unsigned type, unsigned long count
this->serviceIO.subscriptionUpdate ( this->addr, type, count, pfl, notify );
}
inline void dbChannelIO::lock () const
{
dbScanLock ( this->addr.precord );
}
inline void dbChannelIO::unlock () const
{
dbScanUnlock ( this->addr.precord );
}
inline dbEventSubscription dbChannelIO::subscribe ( dbSubscriptionIO &subscr, unsigned mask )
{
return this->serviceIO.subscribe ( this->addr, subscr, mask );

View File

@@ -15,16 +15,6 @@
* 505 665 1831
*/
inline void dbPutNotifyBlocker::lock () const
{
this->chan.lock ();
}
inline void dbPutNotifyBlocker::unlock () const
{
this->chan.unlock ();
}
inline void dbPutNotifyBlocker::destroy ()
{
delete this;
@@ -32,10 +22,12 @@ inline void dbPutNotifyBlocker::destroy ()
inline void * dbPutNotifyBlocker::operator new ( size_t size )
{
epicsAutoMutex locker ( dbPutNotifyBlocker::freeListMutex );
return dbPutNotifyBlocker::freeList.allocate ( size );
}
inline void dbPutNotifyBlocker::operator delete ( void *pCadaver, size_t size )
{
epicsAutoMutex locker ( dbPutNotifyBlocker::freeListMutex );
dbPutNotifyBlocker::freeList.release ( pCadaver, size );
}

View File

@@ -37,6 +37,7 @@
#define S_db_Pending (M_dbAccess|37)
tsFreeList <dbPutNotifyBlocker> dbPutNotifyBlocker::freeList;
epicsMutex dbPutNotifyBlocker::freeListMutex;
dbPutNotifyBlocker::dbPutNotifyBlocker ( dbChannelIO &chanIn ) :
pPN (0), chan ( chanIn )
@@ -45,18 +46,16 @@ dbPutNotifyBlocker::dbPutNotifyBlocker ( dbChannelIO &chanIn ) :
dbPutNotifyBlocker::~dbPutNotifyBlocker ()
{
this->lock ();
dbAutoScanLockCA ( this->chan );
if ( this->pPN ) {
this->pPN->destroy ();
this->pPN->cancel ();
}
this->unlock ();
}
void dbPutNotifyBlocker::putNotifyDestroyNotify ()
{
this->lock ();
dbAutoScanLockCA ( this->chan );
this->pPN = 0;
this->unlock ();
}
dbChannelIO & dbPutNotifyBlocker::channel () const
@@ -73,38 +72,38 @@ int dbPutNotifyBlocker::initiatePutNotify ( cacNotify &notify,
return ECA_ALLOCMEM;
}
// wait for current put notify to complete
this->lock ();
if ( this->pPN ) {
epicsTime begin = epicsTime::getCurrent ();
do {
this->unlock ();
this->block.wait ( 1.0 );
if ( epicsTime::getCurrent () - begin > 30.0 ) {
pIO->destroy ();
return ECA_PUTCBINPROG;
while ( true ) {
{
dbAutoScanLockCA ( this->chan );
if ( ! this->pPN ) {
this->pPN = pIO;
int status = this->pPN->initiate ( addr, type, count, pValue );
if ( status != ECA_NORMAL ) {
pIO->cancel ();
this->pPN = 0;
}
return status;
}
this->lock ();
} while ( this->pPN );
}
// wait for put notify in progress to complete
this->block.wait ( 1.0 );
epicsTime begin = epicsTime::getCurrent ();
if ( epicsTime::getCurrent () - begin > 30.0 ) {
pIO->cancel ();
return ECA_PUTCBINPROG;
}
}
this->pPN = pIO;
int status = this->pPN->initiate ( addr, type, count, pValue );
if ( status != ECA_NORMAL ) {
this->pPN->destroy ();
this->pPN = 0;
}
this->unlock ();
return status;
}
extern "C" void putNotifyCompletion ( putNotify *ppn )
{
dbPutNotifyBlocker *pBlocker = static_cast < dbPutNotifyBlocker * > ( ppn->usrPvt );
pBlocker->lock ();
pBlocker->pPN->completion ();
pBlocker->pPN->destroy ();
pBlocker->pPN = 0;
pBlocker->unlock ();
{
dbAutoScanLockCA ( pBlocker->chan );
pBlocker->pPN->completion ();
pBlocker->pPN->cancel ();
pBlocker->pPN = 0;
}
pBlocker->block.signal ();
}