first cut

This commit is contained in:
Jeff Hill
2000-08-25 01:25:25 +00:00
parent a3341382b8
commit 02df98b82c
2 changed files with 213 additions and 0 deletions

View 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;
}

View 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