/** * Copyright - See the COPYRIGHT that is included with this distribution. * pvAccessCPP is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ #include #include #include #include #include #include #include #include #include using namespace epics::pvData; namespace epics { namespace pvAccess { BlockingTCPConnector::BlockingTCPConnector( Context::shared_pointer const & context, int receiveBufferSize, float beaconInterval) : _context(context), _namedLocker(), _receiveBufferSize(receiveBufferSize), _beaconInterval(beaconInterval) { } BlockingTCPConnector::~BlockingTCPConnector() { } SOCKET BlockingTCPConnector::tryConnect(osiSockAddr& address, int tries) { char strBuffer[64]; ipAddrToDottedIP(&address.ia, strBuffer, sizeof(strBuffer)); for(int tryCount = 0; tryCount& responseHandler, osiSockAddr& address, int8 transportRevision, int16 priority) { SOCKET socket = INVALID_SOCKET; char ipAddrStr[64]; ipAddrToDottedIP(&address.ia, ipAddrStr, sizeof(ipAddrStr)); Context::shared_pointer context = _context.lock(); // first try to check cache w/o named lock... Transport::shared_pointer transport = context->getTransportRegistry()->get("TCP", &address, priority); if(transport.get()) { LOG(logLevelDebug, "Reusing existing connection to PVA server: %s", ipAddrStr); if (transport->acquire(client)) return transport; } bool lockAcquired = _namedLocker.acquireSynchronizationObject(&address, LOCK_TIMEOUT); if(lockAcquired) { try { // ... transport created during waiting in lock transport = context->getTransportRegistry()->get("TCP", &address, priority); if(transport.get()) { LOG(logLevelDebug, "Reusing existing connection to PVA server: %s", ipAddrStr); if (transport->acquire(client)) return transport; } LOG(logLevelDebug, "Connecting to PVA server: %s", ipAddrStr); socket = tryConnect(address, 3); // verify if(socket==INVALID_SOCKET) { LOG(logLevelDebug, "Connection to PVA server %s failed.", ipAddrStr); std::ostringstream temp; temp<<"Failed to verify TCP connection to '"<verify(3000)) { LOG( logLevelDebug, "Connection to PVA server %s failed to be validated, closing it.", ipAddrStr); std::ostringstream temp; temp<<"Failed to verify TCP connection to '"<close(); else if(socket!=INVALID_SOCKET) epicsSocketDestroy(socket); _namedLocker.releaseSynchronizationObject(&address); throw; } catch(...) { if(transport.get()) transport->close(); else if(socket!=INVALID_SOCKET) epicsSocketDestroy(socket); _namedLocker.releaseSynchronizationObject(&address); throw; } } else { std::ostringstream temp; temp<<"Failed to obtain synchronization lock for '"<