first cut
This commit is contained in:
130
src/libCom/misc/ipAddrToAsciiAsynchronous.cpp
Normal file
130
src/libCom/misc/ipAddrToAsciiAsynchronous.cpp
Normal file
@@ -0,0 +1,130 @@
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
*
|
||||
* L O S A L A M O S
|
||||
* Los Alamos National Laboratory
|
||||
* Los Alamos, New Mexico 87545
|
||||
*
|
||||
* Copyright, 1986, The Regents of the University of California.
|
||||
*
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
*/
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "osiThread.h"
|
||||
#include "ipAddrToAsciiAsynchronous.h"
|
||||
|
||||
osiMutex ipAddrToAsciiEngine::mutex;
|
||||
|
||||
ipAddrToAsciiEngine::ipAddrToAsciiEngine ( const char *pName ) :
|
||||
osiThread ( pName, 0x1000, threadPriorityLow ), nextId ( 0u ),
|
||||
exitFlag ( false )
|
||||
{
|
||||
this->start (); // start the thread
|
||||
}
|
||||
|
||||
ipAddrToAsciiEngine::~ipAddrToAsciiEngine ()
|
||||
{
|
||||
ipAddrToAsciiAsynchronous * pItem = this->labor.first ();
|
||||
|
||||
this->event.signal ();
|
||||
this->exitFlag = true;
|
||||
this->threadExit.wait ();
|
||||
|
||||
// force IO completion for any items that remain
|
||||
ipAddrToAsciiEngine::mutex.lock ();
|
||||
while ( ( pItem = this->labor.first () ) ) {
|
||||
pItem->pEngine = 0u;
|
||||
sockAddrToA ( &pItem->addr.sa, this->nameTmp,
|
||||
sizeof ( this->nameTmp ) );
|
||||
pItem->ioCompletionNotify ( this->nameTmp );
|
||||
}
|
||||
ipAddrToAsciiEngine::mutex.unlock ();
|
||||
}
|
||||
|
||||
void ipAddrToAsciiEngine::entryPoint ()
|
||||
{
|
||||
osiSockAddr addr;
|
||||
unsigned id;
|
||||
|
||||
while ( ! this->exitFlag ) {
|
||||
while ( true ) {
|
||||
ipAddrToAsciiEngine::mutex.lock ();
|
||||
ipAddrToAsciiAsynchronous * pItem = this->labor.first ();
|
||||
if ( pItem ) {
|
||||
addr = pItem->addr;
|
||||
id = pItem->id;
|
||||
}
|
||||
else {
|
||||
this->mutex.unlock ();
|
||||
break;
|
||||
}
|
||||
ipAddrToAsciiEngine::mutex.unlock ();
|
||||
|
||||
// knowing DNS, this could take a very long time
|
||||
sockAddrToA ( &addr.sa, this->nameTmp, sizeof ( this->nameTmp ) );
|
||||
|
||||
ipAddrToAsciiEngine::mutex.lock ();
|
||||
pItem = this->labor.get ();
|
||||
if ( pItem ) {
|
||||
if ( id == pItem->id ) {
|
||||
pItem->ioCompletionNotify ( this->nameTmp );
|
||||
pItem->pEngine = 0u;
|
||||
}
|
||||
else {
|
||||
this->labor.push ( *pItem );
|
||||
}
|
||||
}
|
||||
else {
|
||||
ipAddrToAsciiEngine::mutex.unlock ();
|
||||
break;
|
||||
}
|
||||
ipAddrToAsciiEngine::mutex.unlock ();
|
||||
}
|
||||
this->event.wait ();
|
||||
}
|
||||
this->threadExit.signal ();
|
||||
}
|
||||
|
||||
ipAddrToAsciiAsynchronous::ipAddrToAsciiAsynchronous
|
||||
( const osiSockAddr &addrIn ) :
|
||||
addr ( addrIn ), pEngine ( 0u )
|
||||
{
|
||||
}
|
||||
|
||||
ipAddrToAsciiAsynchronous::~ipAddrToAsciiAsynchronous ()
|
||||
{
|
||||
ipAddrToAsciiEngine::mutex.lock ();
|
||||
if ( this->pEngine ) {
|
||||
this->pEngine->labor.remove ( *this );
|
||||
}
|
||||
ipAddrToAsciiEngine::mutex.unlock ();
|
||||
}
|
||||
|
||||
epicsShareFunc bool ipAddrToAsciiAsynchronous::ioInitiate ( ipAddrToAsciiEngine &engine )
|
||||
{
|
||||
bool success;
|
||||
|
||||
ipAddrToAsciiEngine::mutex.lock ();
|
||||
// put some reasonable limit on queue expansion
|
||||
if ( engine.labor.count () < 16u ) {
|
||||
this->id = engine.nextId++;
|
||||
this->pEngine = &engine;
|
||||
engine.labor.add ( *this );
|
||||
success = true;
|
||||
}
|
||||
else {
|
||||
success = false;
|
||||
}
|
||||
ipAddrToAsciiEngine::mutex.unlock ();
|
||||
|
||||
if ( success ) {
|
||||
engine.event.signal ();
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
83
src/libCom/misc/ipAddrToAsciiAsynchronous.h
Normal file
83
src/libCom/misc/ipAddrToAsciiAsynchronous.h
Normal file
@@ -0,0 +1,83 @@
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
*
|
||||
* L O S A L A M O S
|
||||
* Los Alamos National Laboratory
|
||||
* Los Alamos, New Mexico 87545
|
||||
*
|
||||
* Copyright, 1986, The Regents of the University of California.
|
||||
*
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
*/
|
||||
|
||||
#ifndef ipAddrToAsciiAsynchronous_h
|
||||
#define ipAddrToAsciiAsynchronous_h
|
||||
|
||||
#include "osiMutex.h"
|
||||
#include "osiSock.h"
|
||||
#include "tsDLList.h"
|
||||
#include "shareLib.h"
|
||||
|
||||
class ipAddrToAsciiAsynchronous;
|
||||
|
||||
// - this class executes the synchronous DNS query
|
||||
// - it creates one thread
|
||||
class ipAddrToAsciiEngine : public osiThread {
|
||||
public:
|
||||
epicsShareFunc ipAddrToAsciiEngine ( const char *pName );
|
||||
epicsShareFunc ~ipAddrToAsciiEngine ();
|
||||
private:
|
||||
tsDLList < ipAddrToAsciiAsynchronous > labor;
|
||||
osiEvent event;
|
||||
osiEvent threadExit;
|
||||
char nameTmp [1024];
|
||||
unsigned nextId;
|
||||
bool exitFlag;
|
||||
static osiMutex mutex;
|
||||
void entryPoint ();
|
||||
friend class ipAddrToAsciiAsynchronous;
|
||||
};
|
||||
|
||||
// - this class implements the asynchronous DNS query
|
||||
// - it completes early with the host name in dotted IP address form
|
||||
// if the ipAddrToAsciiEngine is destroyed before IO completion
|
||||
// - ioInitiate fails if there are too many items already in
|
||||
// the engine's queue.
|
||||
//
|
||||
class ipAddrToAsciiAsynchronous :
|
||||
public tsDLNode < ipAddrToAsciiAsynchronous > {
|
||||
public:
|
||||
epicsShareFunc ipAddrToAsciiAsynchronous ( const osiSockAddr &addr );
|
||||
epicsShareFunc virtual ~ipAddrToAsciiAsynchronous ();
|
||||
epicsShareFunc bool ioInitiate ( ipAddrToAsciiEngine &engine );
|
||||
epicsShareFunc bool identicalAddress ( const osiSockAddr &addr ) const;
|
||||
epicsShareFunc osiSockAddr address () const;
|
||||
virtual void ioCompletionNotify ( const char *pHostName ) = 0;
|
||||
private:
|
||||
osiSockAddr addr;
|
||||
ipAddrToAsciiEngine *pEngine;
|
||||
unsigned id;
|
||||
friend class ipAddrToAsciiEngine;
|
||||
};
|
||||
|
||||
inline osiSockAddr ipAddrToAsciiAsynchronous::address () const
|
||||
{
|
||||
return this->addr;
|
||||
}
|
||||
|
||||
inline bool ipAddrToAsciiAsynchronous::identicalAddress ( const osiSockAddr &addrIn ) const
|
||||
{
|
||||
if ( this->addr.sa.sa_family == AF_INET && addrIn.sa.sa_family == AF_INET ) {
|
||||
return this->addr.ia.sin_addr.s_addr == addrIn.ia.sin_addr.s_addr &&
|
||||
this->addr.ia.sin_port == addrIn.ia.sin_port;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // ifdef ipAddrToAsciiAsynchronous_h
|
||||
Reference in New Issue
Block a user