22 #define EPICS_PRIVATE_API 40 public tsDLNode < ipAddrToAsciiTransactionPrivate > {
45 void show (
unsigned level )
const;
49 < ipAddrToAsciiTransactionPrivate, 0x80 > & ))
56 void operator delete (
void * );
58 ipAddrToAsciiTransactionPrivate & operator = (
const ipAddrToAsciiTransactionPrivate & );
63 # pragma warning ( push ) 64 # pragma warning ( disable:4660 ) 71 # pragma warning ( pop ) 75 static void ipAddrToAsciiEngineGlobalMutexConstruct (
void * );
79 struct ipAddrToAsciiGlobal :
public epicsThreadRunable {
80 ipAddrToAsciiGlobal();
81 virtual ~ipAddrToAsciiGlobal() {}
95 ipAddrToAsciiTransactionPrivate * pCurrent;
97 ipAddrToAsciiTransactionPrivate * pActive;
98 unsigned cancelPendingCount;
100 bool callbackInProgress;
111 void show (
unsigned level )
const;
137 static void ipAddrToAsciiEngineGlobalMutexConstruct (
void * )
141 }
catch (std::exception& e) {
142 errlogPrintf(
"ipAddrToAsciiEnginePrivate ctor fails with: %s\n", e.what());
146 void ipAddrToAsciiEngine::cleanup()
165 & ipAddrToAsciiEngineGlobalMutexOnceFlag,
166 ipAddrToAsciiEngineGlobalMutexConstruct, 0 );
168 throw std::runtime_error(
"ipAddrToAsciiEngine::allocate fails");
172 ipAddrToAsciiGlobal::ipAddrToAsciiGlobal () :
173 mutex(__FILE__, __LINE__),
174 thread ( *
this,
"ipToAsciiProxy",
177 pCurrent ( 0 ), pActive ( 0 ), cancelPendingCount ( 0u ), exitFlag (
false ),
178 callbackInProgress (
false )
180 this->thread.start ();
190 throw std::logic_error(
"Engine release() called again!");
199 ipAddrToAsciiTransactionPrivate *trn = it.pointer();
204 pEngine->labor.remove(*trn);
209 if (pEngine->pCurrent &&
this==&pEngine->pCurrent->engine) {
210 pEngine->pCurrent->pending =
false;
211 pEngine->pCurrent = 0;
215 pEngine->cancelPendingCount++;
216 while(pEngine->pActive &&
this==&pEngine->pActive->engine
217 && ! pEngine->thread.isCurrentThread()) {
219 pEngine->destructorBlockEvent.wait();
221 pEngine->cancelPendingCount--;
222 if(pEngine->cancelPendingCount)
223 pEngine->destructorBlockEvent.signal();
227 last = 0==--refcount;
237 printf (
"ipAddrToAsciiEngine at %p with %u requests pending\n",
238 static_cast <const void *> (
this), this->pEngine->labor.count () );
241 pItem = this->pEngine->labor.firstIter ();
242 while ( pItem.
valid () ) {
243 pItem->
show ( level - 1u );
249 this->pEngine->mutex.show ( level - 2u );
250 printf (
"laborEvent:\n" );
251 this->pEngine->laborEvent.show ( level - 2u );
252 printf (
"exitFlag boolean = %u\n", this->pEngine->exitFlag );
253 printf (
"exit event:\n" );
257 inline void * ipAddrToAsciiTransactionPrivate::operator
new (
size_t size,
tsFreeList 260 return freeList.allocate ( size );
263 #ifdef CXX_PLACEMENT_DELETE 264 inline void ipAddrToAsciiTransactionPrivate::operator
delete (
void * pTrans,
tsFreeList 267 freeList.release ( pTrans );
271 void ipAddrToAsciiTransactionPrivate::operator
delete (
void * )
278 errlogPrintf (
"%s:%d this compiler is confused about placement delete - memory was probably leaked",
279 __FILE__, __LINE__ );
287 throw std::logic_error(
"createTransaction() on release()'d ipAddrToAsciiEngine");
291 ipAddrToAsciiTransactionPrivate *ret =
new ( this->pEngine->transactionFreeList ) ipAddrToAsciiTransactionPrivate ( *
this );
298 void ipAddrToAsciiGlobal::run ()
301 while ( ! this->exitFlag ) {
304 this->laborEvent.wait ();
307 ipAddrToAsciiTransactionPrivate * pItem = this->labor.get ();
312 this->pCurrent = pItem;
314 if ( this->exitFlag )
317 sizeof ( this->nameTmp ) );
323 sockAddrToA ( &addr.
sa, this->nameTmp, sizeof ( this->nameTmp ) );
329 if ( ! this->pCurrent ) {
336 ipAddrToAsciiTransactionPrivate *pCur = pActive = pCurrent;
337 this->callbackInProgress =
true;
345 this->callbackInProgress =
false;
348 if ( this->pCurrent ) {
349 this->pCurrent->pending =
false;
352 if ( this->cancelPendingCount ) {
353 this->destructorBlockEvent.signal ();
363 memset ( & this->addr,
'\0',
sizeof ( this->addr ) );
364 this->addr.sa.sa_family = AF_UNSPEC;
380 if ( pGlobal->pCurrent ==
this &&
381 pGlobal->callbackInProgress &&
382 ! pGlobal->thread.isCurrentThread() ) {
385 assert ( pGlobal->cancelPendingCount < UINT_MAX );
386 pGlobal->cancelPendingCount++;
389 pGlobal->destructorBlockEvent.wait ();
391 assert ( pGlobal->cancelPendingCount > 0u );
392 pGlobal->cancelPendingCount--;
394 if ( pGlobal->cancelPendingCount ) {
395 pGlobal->destructorBlockEvent.signal ();
401 if ( pGlobal->pCurrent ==
this ) {
403 pGlobal->pCurrent = 0;
407 pGlobal->labor.remove ( *
this );
430 errlogPrintf(
"Warning: ipAddrToAscii on transaction with release()'d ipAddrToAsciiEngine");
433 }
else if ( !this->
pending && pGlobal->labor.count () < 16u ) {
438 pGlobal->labor.add ( *
this );
447 pGlobal->laborEvent.signal ();
450 char autoNameTmp[256];
452 sizeof ( autoNameTmp ) );
467 printf (
"ipAddrToAsciiTransactionPrivate for address %s\n", ipAddr );
470 static_cast <void *> ( & this->
engine ) );
471 this->
pCB->
show ( level - 1u );
unsigned epicsStdCall sockAddrToDottedIP(const struct sockaddr *paddr, char *pBuf, unsigned bufSize)
ipAddrToAsciiTransactionPrivate(class ipAddrToAsciiEnginePrivate &engineIn)
osiSockAddr address() const
#define assert(exp)
Declare that a condition should be true.
virtual void transactionComplete(const char *pHostName)=0
void ipAddrToAscii(const osiSockAddr &, ipAddrToAsciiCallBack &)
virtual ~ipAddrToAsciiTransaction()=0
ipAddrToAsciiEnginePrivate()
virtual void show(unsigned level) const
LIBCOM_API unsigned int epicsStdCall epicsThreadGetStackSize(epicsThreadStackSizeClass size)
ipAddrToAsciiTransaction & createTransaction()
#define EPICS_THREAD_ONCE_INIT
virtual ~ipAddrToAsciiEnginePrivate()
APIs for the epicsMutex mutual exclusion semaphore.
LIBCOM_API void epicsStdCall epicsThreadOnce(epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg)
#define epicsThreadPriorityLow
Extended replacement for the Posix exit and atexit routines.
static ipAddrToAsciiGlobal * pEngine
int errlogPrintf(const char *pFormat,...)
ipAddrToAsciiCallBack * pCB
APIs for the epicsEvent binary semaphore.
void show(unsigned level) const
static ipAddrToAsciiEngine & allocate()
unsigned epicsStdCall sockAddrToA(const struct sockaddr *paddr, char *pBuf, unsigned bufSize)
virtual ~ipAddrToAsciiTransactionPrivate()
void show(unsigned level) const
virtual ~ipAddrToAsciiCallBack()=0
virtual ~ipAddrToAsciiEngine()=0
C++ and C descriptions for a thread.
ipAddrToAsciiEnginePrivate & engine
epicsPlacementDeleteOperator((void *, tsFreeList< ipAddrToAsciiTransactionPrivate, 0x80 > &)) osiSockAddr addr