From 130e6f96458a5a82fdd09bca342c45a74e578491 Mon Sep 17 00:00:00 2001 From: miha_vitorovic Date: Fri, 7 Jan 2011 15:08:53 +0100 Subject: [PATCH 1/6] Added some additional commands to 'MessageCommands' enum. --- pvAccessApp/remote/remote.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pvAccessApp/remote/remote.h b/pvAccessApp/remote/remote.h index 46f7a12..9f0c547 100644 --- a/pvAccessApp/remote/remote.h +++ b/pvAccessApp/remote/remote.h @@ -33,11 +33,12 @@ namespace epics { enum MessageCommands { CMD_BEACON = 0, CMD_CONNECTION_VALIDATION = 1, CMD_ECHO = 2, - CMD_SEARCH = 3, CMD_INTROSPECTION_SEARCH = 5, - CMD_CREATE_CHANNEL = 7, CMD_DESTROY_CHANNEL = 8, CMD_GET = 10, - CMD_PUT = 11, CMD_PUT_GET = 12, CMD_MONITOR = 13, CMD_ARRAY = 14, + CMD_SEARCH = 3, CMD_SEARCH_RESPONSE = 4, + CMD_INTROSPECTION_SEARCH = 5, CMD_CREATE_CHANNEL = 7, + CMD_DESTROY_CHANNEL = 8, CMD_GET = 10, CMD_PUT = 11, + CMD_PUT_GET = 12, CMD_MONITOR = 13, CMD_ARRAY = 14, CMD_CANCEL_REQUEST = 15, CMD_PROCESS = 16, CMD_GET_FIELD = 17, - CMD_RPC = 20, + CMD_MESSAGE = 18, CMD_MULTIPLE_DATA = 19, CMD_RPC = 20, }; /** From 29db1970350464b55ecb271116e20b781e1463b3 Mon Sep 17 00:00:00 2001 From: miha_vitorovic Date: Fri, 7 Jan 2011 16:28:42 +0100 Subject: [PATCH 2/6] inetAddressUtil.cpp: - the ported version of 'getBroadcastAddresses' compiles. TODO - test and debug. --- pvAccessApp/utils/inetAddressUtil.cpp | 190 +++++++++++++++++--------- 1 file changed, 122 insertions(+), 68 deletions(-) diff --git a/pvAccessApp/utils/inetAddressUtil.cpp b/pvAccessApp/utils/inetAddressUtil.cpp index 217c740..15e7086 100644 --- a/pvAccessApp/utils/inetAddressUtil.cpp +++ b/pvAccessApp/utils/inetAddressUtil.cpp @@ -15,6 +15,7 @@ #include #include #include +#include /* standard */ #include @@ -29,81 +30,134 @@ using namespace epics::pvData; namespace epics { namespace pvAccess { - /* copied from EPICS v3 ca/iocinf.cpp - * removeDuplicateAddresses () + /* + * osiSockDiscoverBroadcastAddresses () je v + * /opt/epics/base/src/libCom/osi/os/default/osdNetIntf.c */ - void removeDuplicateAddresses(ELLLIST *pDestList, ELLLIST *pSrcList, - int silent) { - ELLNODE *pRawNode; - - while((pRawNode = ellGet(pSrcList))) { - STATIC_ASSERT(offsetof(osiSockAddrNode, node)==0); - osiSockAddrNode *pNode = - reinterpret_cast (pRawNode); - osiSockAddrNode *pTmpNode; - - if(pNode->addr.sa.sa_family==AF_INET) { - - pTmpNode = (osiSockAddrNode *)ellFirst (pDestList); // X aCC 749 - while(pTmpNode) { - if(pTmpNode->addr.sa.sa_family==AF_INET) { - if(pNode->addr.ia.sin_addr.s_addr - ==pTmpNode->addr.ia.sin_addr.s_addr - &&pNode->addr.ia.sin_port - ==pTmpNode->addr.ia.sin_port) { - if(!silent) { - char buf[64]; - ipAddrToDottedIP(&pNode->addr.ia, buf, - sizeof(buf)); - fprintf( - stderr, - "Warning: Duplicate EPICS CA Address list entry \"%s\" discarded\n", - buf); - } - free(pNode); - pNode = NULL; - break; - } - } - pTmpNode = (osiSockAddrNode *)ellNext (&pTmpNode->node); // X aCC 749 - } - if(pNode) { - ellAdd(pDestList, &pNode->node); - } - } - else { - ellAdd(pDestList, &pNode->node); - } - } - } InetAddrVector* getBroadcastAddresses(SOCKET sock) { - ELLLIST bcastList; - ELLLIST tmpList; - osiSockAddr addr; + static const unsigned nelem = 100; + int status; + struct ifconf ifconf; + struct ifreq* pIfreqList; + struct ifreq *pifreq; + osiSockAddr* pNewNode; - ellInit ( &bcastList ); // X aCC 392 - ellInit ( &tmpList ); // X aCC 392 + InetAddrVector* retVector = new InetAddrVector(); - addr.ia.sin_family = AF_UNSPEC; - osiSockDiscoverBroadcastAddresses(&bcastList, sock, &addr); - removeDuplicateAddresses(&tmpList, &bcastList, 1); - // forcePort ( &bcastList, port ); // if needed copy from ca/iocinf.cpp - - int size = ellCount(&bcastList ); - InetAddrVector* retVector = new InetAddrVector(size); - - ELLNODE *pRawNode; - - while((pRawNode = ellGet(&tmpList))) { - osiSockAddrNode *pNode = - reinterpret_cast (pRawNode); - osiSockAddr* posa = new osiSockAddr; - memcpy(posa, &(pNode->addr), sizeof(osiSockAddr)); - retVector->push_back(posa); - free(pNode); // using free because it is allocated by calloc + /* + * use pool so that we avoid using too much stack space + * + * nelem is set to the maximum interfaces + * on one machine here + */ + pIfreqList = new ifreq[nelem]; + if(!pIfreqList) { + errlogSevPrintf( errlogMajor, + "osiSockDiscoverBroadcastAddresses(): no memory to complete request\n"); + return retVector; } + // get number of interfaces + ifconf.ifc_len = nelem*sizeof(ifreq); + ifconf.ifc_req = pIfreqList; + status = socket_ioctl (sock, SIOCGIFCONF, &ifconf); + if(status<0||ifconf.ifc_len==0) { + errlogSevPrintf( + errlogMinor, + "osiSockDiscoverBroadcastAddresses(): unable to fetch network interface configuration"); + delete[] pIfreqList; + return retVector; + } + + for(int i = 0; i<=ifconf.ifc_len; i++) { + pifreq = &pIfreqList[i]; + + /* + * If its not an internet interface then dont use it + */ + if(pifreq->ifr_addr.sa_family!=AF_INET) continue; + + status = socket_ioctl ( sock, SIOCGIFFLAGS, pifreq ); + if(status) { + errlogSevPrintf( + errlogMinor, + "osiSockDiscoverBroadcastAddresses(): net intf flags fetch for \"%s\" failed\n", + pifreq->ifr_name); + continue; + } + + /* + * dont bother with interfaces that have been disabled + */ + if(!(pifreq->ifr_flags&IFF_UP)) continue; + + /* + * dont use the loop back interface + */ + if(pifreq->ifr_flags&IFF_LOOPBACK) continue; + + pNewNode = new osiSockAddr; + if(pNewNode==NULL) { + errlogSevPrintf(errlogMajor, + "osiSockDiscoverBroadcastAddresses(): no memory available for configuration\n"); + delete[] pIfreqList; + return retVector; + } + + /* + * If this is an interface that supports + * broadcast fetch the broadcast address. + * + * Otherwise if this is a point to point + * interface then use the destination address. + * + * Otherwise CA will not query through the + * interface. + */ + if(pifreq->ifr_flags&IFF_BROADCAST) { + status = socket_ioctl (sock, SIOCGIFBRDADDR, pifreq); + if(status) { + errlogSevPrintf( + errlogMinor, + "osiSockDiscoverBroadcastAddresses(): net intf \"%s\": bcast addr fetch fail\n", + pIfreqList->ifr_name); + delete pNewNode; + continue; + } + pNewNode->sa = pifreq->ifr_broadaddr; + } +#ifdef IFF_POINTOPOINT + else if(pIfreqList->ifr_flags&IFF_POINTOPOINT) { + status = socket_ioctl ( sock, SIOCGIFDSTADDR, pifreq); + if(status) { + errlogSevPrintf( + errlogMinor, + "osiSockDiscoverBroadcastAddresses(): net intf \"%s\": pt to pt addr fetch fail\n", + pifreq->ifr_name); + delete pNewNode; + continue; + } + pNewNode->sa = pifreq->ifr_dstaddr; + } +#endif + else { + errlogSevPrintf( + errlogMinor, + "osiSockDiscoverBroadcastAddresses(): net intf \"%s\": not point to point or bcast?\n", + pifreq->ifr_name); + delete pNewNode; + continue; + } + + /* + * LOCK applied externally + */ + retVector->push_back(pNewNode); + } + + delete[] pIfreqList; + return retVector; } From e26e05bfbfc09a289debdb609f9fd2989268c853 Mon Sep 17 00:00:00 2001 From: Gasper Jansa Date: Sun, 9 Jan 2011 20:15:00 +0100 Subject: [PATCH 3/6] epics mutex now used in named lock pattern --- pvAccessApp/utils/namedLockPattern.h | 5 +++ pvAccessApp/utils/referenceCountingLock.cpp | 49 +++++++++++---------- pvAccessApp/utils/referenceCountingLock.h | 11 ++++- testApp/utils/namedLockPatternTest.cpp | 8 ++-- 4 files changed, 46 insertions(+), 27 deletions(-) diff --git a/pvAccessApp/utils/namedLockPattern.h b/pvAccessApp/utils/namedLockPattern.h index d57455a..26b6c1c 100644 --- a/pvAccessApp/utils/namedLockPattern.h +++ b/pvAccessApp/utils/namedLockPattern.h @@ -34,10 +34,15 @@ public: virtual ~NamedLockPattern() {}; /** * Acquire synchronization lock for named object. + * + * NOTE: Argument msecs is currently not supported due to + * Darwin OS not supporting pthread_mutex_timedlock. May be changed in the future. + * * @param name name of the object whose lock to acquire. * @param msec the number of milleseconds to wait. * An argument less than or equal to zero means not to wait at all. * @return true if acquired, false othwerwise. + * NOTE: currently this routine always returns true. Look above for explanation. */ bool acquireSynchronizationObject(const Key name, const int64 msec); /** diff --git a/pvAccessApp/utils/referenceCountingLock.cpp b/pvAccessApp/utils/referenceCountingLock.cpp index 2b45005..b618a84 100644 --- a/pvAccessApp/utils/referenceCountingLock.cpp +++ b/pvAccessApp/utils/referenceCountingLock.cpp @@ -8,7 +8,7 @@ namespace epics { namespace pvAccess { ReferenceCountingLock::ReferenceCountingLock(): _references(1) { - pthread_mutexattr_t mutexAttribute; +/* pthread_mutexattr_t mutexAttribute; int32 retval = pthread_mutexattr_init(&mutexAttribute); if(retval != 0) { @@ -31,23 +31,29 @@ ReferenceCountingLock::ReferenceCountingLock(): _references(1) assert(false); } - pthread_mutexattr_destroy(&mutexAttribute); + pthread_mutexattr_destroy(&mutexAttribute);*/ } ReferenceCountingLock::~ReferenceCountingLock() { - pthread_mutex_destroy(&_mutex); +// pthread_mutex_destroy(&_mutex); } bool ReferenceCountingLock::acquire(int64 msecs) { -#ifdef darwin - // timedlock not supported by Darwin OS - return (pthread_mutex_lock(&_mutex) == 0); -#else - struct timespec deltatime; - deltatime.tv_sec = msecs / 1000; - deltatime.tv_nsec = (msecs % 1000) * 1000; + _mutex.lock(); + return true; +/* struct timespec deltatime; + if(msecs > 0) + { + deltatime.tv_sec = msecs / 1000; + deltatime.tv_nsec = (msecs % 1000) * 1000; + } + else + { + deltatime.tv_sec = 0; + deltatime.tv_nsec = 0; + } int32 retval = pthread_mutex_timedlock(&_mutex, &deltatime); if(retval == 0) @@ -55,35 +61,32 @@ bool ReferenceCountingLock::acquire(int64 msecs) return true; } return false; -#endif +*/ } void ReferenceCountingLock::release() { - int retval = pthread_mutex_unlock(&_mutex); + _mutex.unlock(); +/* int retval = pthread_mutex_unlock(&_mutex); if(retval != 0) { //string errMsg = "Error: pthread_mutex_unlock failed: " + string(strerror(retval)); //TODO do something? - } + }*/ } int ReferenceCountingLock::increment() { - //TODO does it really has to be atomic? - return ++_references; - // commented because linking depends on specific version of glibc library - // on i386 target - //return __sync_add_and_fetch(&_references,1); + Lock guard(&_countMutex); + ++_references; + return _references; } int ReferenceCountingLock::decrement() { - //TODO does it really has to be atomic? - return --_references; - // commented because linking depends on specific version of glibc library - // on i386 target - //return __sync_sub_and_fetch(&_references,1); + Lock guard(&_countMutex); + --_references; + return _references; } }} diff --git a/pvAccessApp/utils/referenceCountingLock.h b/pvAccessApp/utils/referenceCountingLock.h index 4153b50..c93f51b 100644 --- a/pvAccessApp/utils/referenceCountingLock.h +++ b/pvAccessApp/utils/referenceCountingLock.h @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -42,9 +43,15 @@ public: /** * Attempt to acquire lock. * + * NOTE: Argument msecs is currently not supported due to + * Darwin OS not supporting pthread_mutex_timedlock. May be changed in the future. + * * @param msecs the number of milleseconds to wait. * An argument less than or equal to zero means not to wait at all. + * * @return true if acquired, false otherwise. + * NOTE: currently this routine always returns true. Look above for explanation. + * */ bool acquire(int64 msecs); /** @@ -65,7 +72,9 @@ public: int decrement(); private: int _references; - pthread_mutex_t _mutex; + Mutex _mutex; + Mutex _countMutex; + //pthread_mutex_t _mutex; }; diff --git a/testApp/utils/namedLockPatternTest.cpp b/testApp/utils/namedLockPatternTest.cpp index edbfbbe..3470afa 100644 --- a/testApp/utils/namedLockPatternTest.cpp +++ b/testApp/utils/namedLockPatternTest.cpp @@ -156,7 +156,7 @@ void* testWorker2(void* p) assert(namedGuard.acquireSynchronizationObject(addr,timeout)); usleep(1); } -#ifndef darwin + //this thread sleeps a while and gets timeout on lock { sleep(1); @@ -165,9 +165,11 @@ void* testWorker2(void* p) addr.ia.sin_port = 1; addr.ia.sin_family = AF_INET; NamedLock namedGuard(namedLockPattern); - assert(!namedGuard.acquireSynchronizationObject(addr,timeout)); + //TODO swap next two lines this if timed lock used + //assert(!namedGuard.acquireSynchronizationObject(addr,timeout)); + assert(namedGuard.acquireSynchronizationObject(addr,timeout)); } -#endif + return NULL; } From e40d6a9d12bac8cfe3eee4a825dac4ad8c94e1ab Mon Sep 17 00:00:00 2001 From: miha_vitorovic Date: Sun, 9 Jan 2011 20:59:02 +0100 Subject: [PATCH 4/6] getBroadcastAddresses working. --- pvAccessApp/utils/inetAddressUtil.cpp | 58 ++++++++++++-------------- testApp/utils/inetAddressUtilsTest.cpp | 12 +++++- 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/pvAccessApp/utils/inetAddressUtil.cpp b/pvAccessApp/utils/inetAddressUtil.cpp index 15e7086..77eac47 100644 --- a/pvAccessApp/utils/inetAddressUtil.cpp +++ b/pvAccessApp/utils/inetAddressUtil.cpp @@ -23,6 +23,8 @@ #include #include #include +#include +#include using namespace std; using namespace epics::pvData; @@ -30,17 +32,14 @@ using namespace epics::pvData; namespace epics { namespace pvAccess { - /* - * osiSockDiscoverBroadcastAddresses () je v - * /opt/epics/base/src/libCom/osi/os/default/osdNetIntf.c + /* port of osiSockDiscoverBroadcastAddresses() in + * epics/base/src/libCom/osi/os/default/osdNetIntf.c */ - InetAddrVector* getBroadcastAddresses(SOCKET sock) { static const unsigned nelem = 100; int status; struct ifconf ifconf; struct ifreq* pIfreqList; - struct ifreq *pifreq; osiSockAddr* pNewNode; InetAddrVector* retVector = new InetAddrVector(); @@ -53,54 +52,54 @@ namespace epics { */ pIfreqList = new ifreq[nelem]; if(!pIfreqList) { - errlogSevPrintf( errlogMajor, - "osiSockDiscoverBroadcastAddresses(): no memory to complete request\n"); + errlogSevPrintf(errlogMajor, + "getBroadcastAddresses(): no memory to complete request"); return retVector; } // get number of interfaces ifconf.ifc_len = nelem*sizeof(ifreq); ifconf.ifc_req = pIfreqList; - status = socket_ioctl (sock, SIOCGIFCONF, &ifconf); + status = ioctl(sock, SIOCGIFCONF, &ifconf); if(status<0||ifconf.ifc_len==0) { errlogSevPrintf( errlogMinor, - "osiSockDiscoverBroadcastAddresses(): unable to fetch network interface configuration"); + "getBroadcastAddresses(): unable to fetch network interface configuration"); delete[] pIfreqList; return retVector; } - for(int i = 0; i<=ifconf.ifc_len; i++) { - pifreq = &pIfreqList[i]; + errlogPrintf("Found %d interfaces\n", ifconf.ifc_len); + for(int i = 0; i<=ifconf.ifc_len; i++) { /* * If its not an internet interface then dont use it */ - if(pifreq->ifr_addr.sa_family!=AF_INET) continue; + if(pIfreqList[i].ifr_addr.sa_family!=AF_INET) continue; - status = socket_ioctl ( sock, SIOCGIFFLAGS, pifreq ); + status = ioctl(sock, SIOCGIFFLAGS, &pIfreqList[i]); if(status) { errlogSevPrintf( errlogMinor, - "osiSockDiscoverBroadcastAddresses(): net intf flags fetch for \"%s\" failed\n", - pifreq->ifr_name); + "getBroadcastAddresses(): net intf flags fetch for \"%s\" failed", + pIfreqList[i].ifr_name); continue; } /* * dont bother with interfaces that have been disabled */ - if(!(pifreq->ifr_flags&IFF_UP)) continue; + if(!(pIfreqList[i].ifr_flags&IFF_UP)) continue; /* * dont use the loop back interface */ - if(pifreq->ifr_flags&IFF_LOOPBACK) continue; + if(pIfreqList[i].ifr_flags&IFF_LOOPBACK) continue; pNewNode = new osiSockAddr; if(pNewNode==NULL) { errlogSevPrintf(errlogMajor, - "osiSockDiscoverBroadcastAddresses(): no memory available for configuration\n"); + "getBroadcastAddresses(): no memory available for configuration"); delete[] pIfreqList; return retVector; } @@ -115,44 +114,41 @@ namespace epics { * Otherwise CA will not query through the * interface. */ - if(pifreq->ifr_flags&IFF_BROADCAST) { - status = socket_ioctl (sock, SIOCGIFBRDADDR, pifreq); + if(pIfreqList[i].ifr_flags&IFF_BROADCAST) { + status = ioctl(sock, SIOCGIFBRDADDR, &pIfreqList[i]); if(status) { errlogSevPrintf( errlogMinor, - "osiSockDiscoverBroadcastAddresses(): net intf \"%s\": bcast addr fetch fail\n", + "getBroadcastAddresses(): net intf \"%s\": bcast addr fetch fail", pIfreqList->ifr_name); delete pNewNode; continue; } - pNewNode->sa = pifreq->ifr_broadaddr; + pNewNode->sa = pIfreqList[i].ifr_broadaddr; } #ifdef IFF_POINTOPOINT else if(pIfreqList->ifr_flags&IFF_POINTOPOINT) { - status = socket_ioctl ( sock, SIOCGIFDSTADDR, pifreq); + status = ioctl(sock, SIOCGIFDSTADDR, &pIfreqList[i]); if(status) { errlogSevPrintf( errlogMinor, - "osiSockDiscoverBroadcastAddresses(): net intf \"%s\": pt to pt addr fetch fail\n", - pifreq->ifr_name); + "getBroadcastAddresses(): net intf \"%s\": pt to pt addr fetch fail", + pIfreqList[i].ifr_name); delete pNewNode; continue; } - pNewNode->sa = pifreq->ifr_dstaddr; + pNewNode->sa = pIfreqList[i].ifr_dstaddr; } #endif else { errlogSevPrintf( errlogMinor, - "osiSockDiscoverBroadcastAddresses(): net intf \"%s\": not point to point or bcast?\n", - pifreq->ifr_name); + "getBroadcastAddresses(): net intf \"%s\": not point to point or bcast?", + pIfreqList[i].ifr_name); delete pNewNode; continue; } - /* - * LOCK applied externally - */ retVector->push_back(pNewNode); } diff --git a/testApp/utils/inetAddressUtilsTest.cpp b/testApp/utils/inetAddressUtilsTest.cpp index ce77ae4..5a594b7 100644 --- a/testApp/utils/inetAddressUtilsTest.cpp +++ b/testApp/utils/inetAddressUtilsTest.cpp @@ -9,7 +9,10 @@ #include #include + #include +#include + #include #include @@ -123,8 +126,15 @@ int main(int argc, char *argv[]) { assert(strncmp(buff->getArray(), src, 16)==0); cout<<"\nPASSED!\n"; - // TODO add test for 'getBroadcastAddresses' + SOCKET socket = epicsSocketCreate(AF_INET, SOCK_STREAM, IPPROTO_TCP); + InetAddrVector* broadcasts = getBroadcastAddresses(socket); + cout<<"Broadcast addresses: "<size()<size(); i++) { + cout<<"Broadcast address: "; + cout<at(i), false)< Date: Sun, 9 Jan 2011 21:00:37 +0100 Subject: [PATCH 5/6] Removed TODO from the comment for getBroadcastAddresses --- pvAccessApp/utils/inetAddressUtil.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pvAccessApp/utils/inetAddressUtil.h b/pvAccessApp/utils/inetAddressUtil.h index 0450839..ee7f381 100644 --- a/pvAccessApp/utils/inetAddressUtil.h +++ b/pvAccessApp/utils/inetAddressUtil.h @@ -33,9 +33,7 @@ namespace epics { /** * returns a vector containing all the IPv4 broadcast addresses * on this machine. IPv6 doesn't have a local broadcast address. - * - * TODO Check implementation/rewrite this - */ + */ InetAddrVector* getBroadcastAddresses(SOCKET sock); /** From 3d59fef56e34a4ba6d640e16f8a15310e36f62b0 Mon Sep 17 00:00:00 2001 From: Gasper Jansa Date: Sun, 9 Jan 2011 21:44:38 +0100 Subject: [PATCH 6/6] some search manager fixes --- pvAccessApp/remote/channelSearchManager.cpp | 3 +- pvAccessApp/remote/channelSearchManager.h | 49 ++++++++++++++++++--- testApp/remote/testChannelSearchManager.cpp | 23 +++++++++- 3 files changed, 68 insertions(+), 7 deletions(-) diff --git a/pvAccessApp/remote/channelSearchManager.cpp b/pvAccessApp/remote/channelSearchManager.cpp index e879dcc..e1c2358 100644 --- a/pvAccessApp/remote/channelSearchManager.cpp +++ b/pvAccessApp/remote/channelSearchManager.cpp @@ -98,13 +98,14 @@ SearchTimer::SearchTimer(ChannelSearchManager* _chanSearchManager, int32 timerIn _requestPendingChannelsMutex(Mutex()), _mutex(Mutex()) { - + _timerNode = new TimerNode(this); } SearchTimer::~SearchTimer() { if(_requestPendingChannels) delete _requestPendingChannels; if(_responsePendingChannels) delete _responsePendingChannels; + if(_timerNode) delete _timerNode; } void SearchTimer::shutdown() diff --git a/pvAccessApp/remote/channelSearchManager.h b/pvAccessApp/remote/channelSearchManager.h index cb5f3c3..b09571c 100644 --- a/pvAccessApp/remote/channelSearchManager.h +++ b/pvAccessApp/remote/channelSearchManager.h @@ -71,11 +71,13 @@ class ChannelImpl; class ChannelSearchManager; class ClientContextImpl : public ClientContext { +private: + Timer* _timer; public: ClientContextImpl() { - + _timer = new Timer("krneki",lowPriority); } virtual Version* getVersion() { @@ -88,7 +90,7 @@ class ClientContextImpl : public ClientContext Timer* getTimer() { - return NULL; + return _timer; } virtual void initialize() { @@ -128,9 +130,9 @@ class ClientContextImpl : public ClientContext return NULL; } - + ~ClientContextImpl() { delete _timer;}; private: - ~ClientContextImpl() {}; + void loadConfiguration() { @@ -237,16 +239,53 @@ class ClientContextImpl : public ClientContext /** * SearchInstance. */ -//TODO document class SearchInstance { public: + /** + * Destructor + */ virtual ~SearchInstance() {}; + /** + * Return channel ID. + * + * @return channel ID. + */ virtual pvAccessID getChannelID() = 0; + /** + * Return channel name. + * + * @return channel channel name. + */ virtual String getChannelName() = 0; + /** + * Removes the owner of this search instance. + */ virtual void unsetListOwnership() = 0; + /** + * Adds this search instance into the provided list and sets it as the owner of this search instance. + * + * @param newOwner a list to which this search instance is added. + * @param ownerMutex mutex belonging to the newOwner list. The mutex will be locked beofe any modification + * to the list will be done. + * @param index index of the owner (which is search timer index). + * + * @throws BaseException if the ownerMutex is NULL. + */ virtual void addAndSetListOwnership(ArrayFIFO* newOwner, Mutex* ownerMutex, int32 index) = 0; + /** + * Removes this search instance from the owner list and also removes the list as the owner of this + * search instance. + * + * @throws BaseException if the ownerMutex is NULL. + */ virtual void removeAndUnsetListOwnership() = 0; + /** + * Returns the index of the owner. + */ virtual int32 getOwnerIndex() = 0; + /** + * Generates request message. + */ virtual bool generateSearchRequestMessage(ByteBuffer* requestMessage, TransportSendControl* control) = 0; /** diff --git a/testApp/remote/testChannelSearchManager.cpp b/testApp/remote/testChannelSearchManager.cpp index 780cda2..1d07806 100644 --- a/testApp/remote/testChannelSearchManager.cpp +++ b/testApp/remote/testChannelSearchManager.cpp @@ -5,14 +5,35 @@ using namespace epics::pvData; using namespace epics::pvAccess; - +class TestSearcInstance : public BaseSearchInstance +{ +public: + TestSearcInstance(string channelName, pvAccessID channelID): _channelID(channelID), _channelName(channelName) {} + pvAccessID getChannelID() { return _channelID;}; + string getChannelName() {return _channelName;}; + void searchResponse(int8 minorRevision, osiSockAddr* serverAddress) {}; +private: + pvAccessID _channelID; + string _channelName; +}; int main(int argc,char *argv[]) { ClientContextImpl* context = new ClientContextImpl(); ChannelSearchManager* manager = new ChannelSearchManager(context); + TestSearcInstance* chan1 = new TestSearcInstance("chan1", 1); + manager->registerChannel(chan1); + + sleep(3); + + manager->cancel(); + context->destroy(); getShowConstructDestruct()->constuctDestructTotals(stdout); + + //if(chan1) delete chan1; + if(manager) delete manager; + if(context) delete context; return(0); }