diff --git a/pvAccessApp/ca/clientFactory.cpp b/pvAccessApp/ca/clientFactory.cpp index e3e73f0..1634c9b 100644 --- a/pvAccessApp/ca/clientFactory.cpp +++ b/pvAccessApp/ca/clientFactory.cpp @@ -2,7 +2,8 @@ /* Author: Matej Sekoranja Date: 2011.2.1 */ #include -#include +#include +#include using namespace epics::pvData; using namespace epics::pvAccess; @@ -12,6 +13,9 @@ ClientContextImpl::shared_pointer ClientFactory::m_context; void ClientFactory::start() { + epicsSignalInstallSigAlarmIgnore (); + epicsSignalInstallSigPipeIgnore (); + Lock guard(m_mutex); if (m_context.get()) return; @@ -22,9 +26,9 @@ void ClientFactory::start() ChannelProvider::shared_pointer provider = m_context->getProvider(); registerChannelProvider(provider); } catch (std::exception &e) { - errlogSevPrintf(errlogMajor, "Unhandled exception caught at %s:%d: %s", __FILE__, __LINE__, e.what()); + LOG(logLevelError, "Unhandled exception caught at %s:%d: %s", __FILE__, __LINE__, e.what()); } catch (...) { - errlogSevPrintf(errlogMajor, "Unhandled exception caught at %s:%d.", __FILE__, __LINE__); + LOG(logLevelError, "Unhandled exception caught at %s:%d.", __FILE__, __LINE__); } } diff --git a/pvAccessApp/remote/blockingClientTCPTransport.cpp b/pvAccessApp/remote/blockingClientTCPTransport.cpp index 6865611..87e0ea4 100644 --- a/pvAccessApp/remote/blockingClientTCPTransport.cpp +++ b/pvAccessApp/remote/blockingClientTCPTransport.cpp @@ -14,7 +14,7 @@ #include /* EPICSv3 */ -#include +#include /* standard */ #include @@ -28,8 +28,8 @@ namespace epics { namespace pvAccess { #define EXCEPTION_GUARD(code) try { code; } \ - catch (std::exception &e) { errlogSevPrintf(errlogMajor, "Unhandled exception caught from code at %s:%d: %s", __FILE__, __LINE__, e.what()); } \ - catch (...) { errlogSevPrintf(errlogMajor, "Unhandled exception caught from code at %s:%d.", __FILE__, __LINE__); } + catch (std::exception &e) { LOG(logLevelError, "Unhandled exception caught from code at %s:%d: %s", __FILE__, __LINE__, e.what()); } \ + catch (...) { LOG(logLevelError, "Unhandled exception caught from code at %s:%d.", __FILE__, __LINE__); } BlockingClientTCPTransport::BlockingClientTCPTransport( Context::shared_pointer const & context, SOCKET channel, @@ -105,7 +105,7 @@ namespace epics { char ipAddrStr[48]; ipAddrToDottedIP(&_socketAddress.ia, ipAddrStr, sizeof(ipAddrStr)); - errlogSevPrintf(errlogInfo, "Acquiring transport to %s.", ipAddrStr); + LOG(logLevelDebug, "Acquiring transport to %s.", ipAddrStr); Lock lock2(_ownersMutex); // TODO double check? if(_closed) return false; @@ -134,8 +134,8 @@ namespace epics { if(refs>0) { char ipAddrStr[48]; ipAddrToDottedIP(&_socketAddress.ia, ipAddrStr, sizeof(ipAddrStr)); - errlogSevPrintf( - errlogInfo, + LOG( + logLevelDebug, "Transport to %s still has %d client(s) active and closing...", ipAddrStr, refs); @@ -161,7 +161,7 @@ namespace epics { char ipAddrStr[48]; ipAddrToDottedIP(&_socketAddress.ia, ipAddrStr, sizeof(ipAddrStr)); - errlogSevPrintf(errlogInfo, "Releasing transport to %s.", ipAddrStr); + LOG(logLevelDebug, "Releasing transport to %s.", ipAddrStr); Lock lock2(_ownersMutex); _owners.erase(clientID); diff --git a/pvAccessApp/remote/blockingServerTCPTransport.cpp b/pvAccessApp/remote/blockingServerTCPTransport.cpp index 7923ca6..644e5e3 100644 --- a/pvAccessApp/remote/blockingServerTCPTransport.cpp +++ b/pvAccessApp/remote/blockingServerTCPTransport.cpp @@ -14,7 +14,7 @@ #include /* EPICSv3 */ -#include +#include /* standard */ #include @@ -49,8 +49,8 @@ namespace epics { char ipAddrStr[64]; ipAddrToDottedIP(&_socketAddress.ia, ipAddrStr, sizeof(ipAddrStr)); - errlogSevPrintf( - errlogInfo, + LOG( + logLevelDebug, "Transport to %s still has %u channel(s) active and closing...", ipAddrStr, (unsigned int)_channels.size()); diff --git a/pvAccessApp/remote/blockingTCPAcceptor.cpp b/pvAccessApp/remote/blockingTCPAcceptor.cpp index 4f2b313..538b4b3 100644 --- a/pvAccessApp/remote/blockingTCPAcceptor.cpp +++ b/pvAccessApp/remote/blockingTCPAcceptor.cpp @@ -10,7 +10,7 @@ #include /* EPICSv3 */ -#include +#include #include #include @@ -55,14 +55,14 @@ namespace epics { int tryCount = 0; while(tryCount<2) { - errlogSevPrintf(errlogInfo, "Creating acceptor to %s.", ipAddrStr); + LOG(logLevelDebug, "Creating acceptor to %s.", ipAddrStr); _serverSocketChannel = epicsSocketCreate(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(_serverSocketChannel==INVALID_SOCKET) { epicsSocketConvertErrnoToString(strBuffer, sizeof(strBuffer)); ostringstream temp; temp<<"Socket create error: "<close(true); - errlogSevPrintf( - errlogInfo, + LOG( + logLevelDebug, "Connection to CA client %s failed to be validated, closing it.", ipAddrStr); return; } - errlogSevPrintf(errlogInfo, "Serving to CA client: %s", ipAddrStr); + LOG(logLevelDebug, "Serving to CA client: %s", ipAddrStr); }// accept succeeded else @@ -217,7 +217,7 @@ namespace epics { transport->verify(); return true; } catch(...) { - errlogSevPrintf(errlogInfo, "Validation of %s failed.", address); + LOG(logLevelDebug, "Validation of %s failed.", address); return false; } } @@ -234,7 +234,7 @@ namespace epics { if(_serverSocketChannel!=INVALID_SOCKET) { char ipAddrStr[48]; ipAddrToDottedIP(&_bindAddress.ia, ipAddrStr, sizeof(ipAddrStr)); - errlogSevPrintf(errlogInfo, "Stopped accepting connections at %s.", ipAddrStr); + LOG(logLevelDebug, "Stopped accepting connections at %s.", ipAddrStr); epicsSocketDestroy(_serverSocketChannel); } diff --git a/pvAccessApp/remote/blockingTCPConnector.cpp b/pvAccessApp/remote/blockingTCPConnector.cpp index 6a4f8bb..63ac2a7 100644 --- a/pvAccessApp/remote/blockingTCPConnector.cpp +++ b/pvAccessApp/remote/blockingTCPConnector.cpp @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include @@ -41,7 +41,7 @@ namespace epics { for(int tryCount = 0; tryCountgetTransportRegistry()->get("TCP", &address, priority); BlockingClientTCPTransport::shared_pointer transport = std::tr1::static_pointer_cast(tt); if(transport.get()) { - errlogSevPrintf(errlogInfo, - "Reusing existing connection to CA server: %s", - ipAddrStr); + LOG(logLevelDebug, + "Reusing existing connection to CA server: %s", + ipAddrStr); if (transport->acquire(client)) return transport; } @@ -95,27 +95,27 @@ namespace epics { tt = context->getTransportRegistry()->get("TCP", &address, priority); transport = std::tr1::static_pointer_cast(tt); if(transport.get()) { - errlogSevPrintf(errlogInfo, - "Reusing existing connection to CA server: %s", - ipAddrStr); + LOG(logLevelDebug, + "Reusing existing connection to CA server: %s", + ipAddrStr); if (transport->acquire(client)) return transport; } - - errlogSevPrintf(errlogInfo, "Connecting to CA server: %s", ipAddrStr); + + LOG(logLevelDebug, "Connecting to CA server: %s", ipAddrStr); socket = tryConnect(address, 3); // verify if(socket==INVALID_SOCKET) { - errlogSevPrintf(errlogMajor, + LOG(logLevelDebug, "Connection to CA server %s failed.", ipAddrStr); ostringstream temp; temp<<"Failed to verify TCP connection to '"<waitUntilVerified(3.0)) { - errlogSevPrintf( - errlogMinor, + LOG( + logLevelDebug, "Connection to CA server %s failed to be validated, closing it.", ipAddrStr); ostringstream temp; @@ -157,13 +157,11 @@ namespace epics { // TODO send security token - errlogSevPrintf(errlogInfo, "Connected to CA server: %s", ipAddrStr); + LOG(logLevelDebug, "Connected to CA server: %s", ipAddrStr); _namedLocker.releaseSynchronizationObject(&address); return transport; } catch(std::exception& ex) { - // TODO - printf("ex %s\n", ex.what()); if(transport.get()) transport->close(true); else if(socket!=INVALID_SOCKET) epicsSocketDestroy(socket); diff --git a/pvAccessApp/remote/blockingTCPTransport.cpp b/pvAccessApp/remote/blockingTCPTransport.cpp index b666950..ff737cf 100644 --- a/pvAccessApp/remote/blockingTCPTransport.cpp +++ b/pvAccessApp/remote/blockingTCPTransport.cpp @@ -20,7 +20,7 @@ #include #include #include -#include +#include /* standard */ #include @@ -133,7 +133,7 @@ namespace epics { _socketSendBufferSize = MAX_TCP_RECV; char errStr[64]; epicsSocketConvertErrnoToString(errStr, sizeof(errStr)); - errlogSevPrintf(errlogMinor, + LOG(logLevelDebug, "Unable to retrieve socket send buffer size: %s", errStr); } @@ -143,7 +143,7 @@ namespace epics { if(retval<0) { char errStr[64]; epicsSocketConvertErrnoToString(errStr, sizeof(errStr)); - errlogSevPrintf(errlogMajor, + LOG(logLevelError, "Error fetching socket remote address: %s", errStr); } @@ -177,7 +177,7 @@ namespace epics { // String threadName = "TCP-receive " + socketAddressString; - errlogSevPrintf(errlogInfo, "Starting thread: %s", threadName.c_str()); + LOG(logLevelDebug, "Starting thread: %s", threadName.c_str()); _rcvThreadId = epicsThreadCreate(threadName.c_str(), epicsThreadPriorityMedium, @@ -189,7 +189,7 @@ namespace epics { // threadName = "TCP-send " + socketAddressString; - errlogSevPrintf(errlogInfo, "Starting thread: %s",threadName.c_str()); + LOG(logLevelDebug, "Starting thread: %s",threadName.c_str()); _sendThreadId = epicsThreadCreate(threadName.c_str(), epicsThreadPriorityMedium, @@ -258,7 +258,7 @@ namespace epics { { char errStr[64]; epicsSocketConvertErrnoToString(errStr, sizeof(errStr)); - errlogSevPrintf(errlogMajor, + LOG(logLevelError, "Socket getsockopt SO_RCVBUF error: %s", errStr); } @@ -394,7 +394,7 @@ namespace epics { // no more data and we have some payload left => read buffer if(_storedPayloadSize>=size) { - //errlogSevPrintf(errlogInfo, + //LOG(logLevelInfo, // "storedPayloadSize >= size, remaining: %d", // _socketBuffer->getRemaining()); @@ -516,8 +516,8 @@ namespace epics { _magicAndVersion = _socketBuffer->getShort(); if((short)(_magicAndVersion&0xFFF0)!=CA_MAGIC_AND_MAJOR_VERSION) { // error... disconnect - errlogSevPrintf( - errlogMinor, + LOG( + logLevelError, "Invalid header received from client %s, disconnecting...", inetAddressToString(_socketAddress).c_str()); close(true); @@ -565,8 +565,8 @@ namespace epics { continue; } else { - errlogSevPrintf( - errlogMajor, + LOG( + logLevelError, "Unknown packet type %d, received from client %s, disconnecting...", type, inetAddressToString(_socketAddress).c_str()); @@ -667,7 +667,7 @@ namespace epics { _sendBuffer->setLimit(_sendBuffer->getSize()); } //} catch(std::exception& e) { - // errlogSevPrintf(errlogMajor, "%s", e.what()); + // LOG(logLevelError, "%s", e.what()); // // error, release lock // clearAndReleaseBuffer(); } catch(...) { @@ -689,7 +689,7 @@ namespace epics { int limit = buffer->getLimit(); int bytesToSend = limit-buffer->getPosition(); - //errlogSevPrintf(errlogInfo,"Total bytes to send: %d", bytesToSend); + //LOG(logLevelInfo,"Total bytes to send: %d", bytesToSend); // limit sending if(bytesToSend>maxBytesToSend) { @@ -697,7 +697,7 @@ namespace epics { buffer->setLimit(buffer->getPosition()+bytesToSend); } - //errlogSevPrintf(errlogInfo, + //LOG(logLevelInfo, // "Sending %d of total %d bytes in the packet to %s.", // bytesToSend, limit, // inetAddressToString(_socketAddress).c_str()); @@ -730,14 +730,14 @@ namespace epics { epicsSocketConvertErrnoToString(errStr, sizeof(errStr)); ostringstream temp; temp<<"error in sending TCP data: "<getPosition(), limit); @@ -746,7 +746,7 @@ namespace epics { */ if(bytesSent==maxBytesToSend) buffer->setLimit(limit); - //errlogSevPrintf(errlogInfo, + //LOG(logLevelInfo, // "Send buffer full for %s, waiting...", // inetAddressToString(_socketAddress)); return false; @@ -766,7 +766,7 @@ namespace epics { buffer->setLimit(buffer->getPosition()+bytesToSend); } - //errlogSevPrintf(errlogInfo, + //LOG(logLevelInfo, // "Sent, position %d of total %d bytes.", // buffer->getPosition(), limit); } // while @@ -843,7 +843,7 @@ namespace epics { endMessage(false);// automatic end (to set payload) } catch(std::exception &e) { - errlogSevPrintf(errlogMajor, "%s", e.what()); + //LOG(logLevelError, "%s", e.what()); _sendBuffer->setPosition(_lastMessageStartPosition); } catch(...) { _sendBuffer->setPosition(_lastMessageStartPosition); @@ -860,7 +860,7 @@ namespace epics { void BlockingTCPTransport::freeConnectionResorces() { freeSendBuffers(); - errlogSevPrintf(errlogInfo, "Connection to %s closed.", + LOG(logLevelDebug, "Connection to %s closed.", inetAddressToString(_socketAddress).c_str()); if(_channel!=INVALID_SOCKET) { @@ -902,7 +902,7 @@ printf("rcvThreadRunnner exception\n"); try { obj->processSendQueue(); } catch (std::exception& ex) { - printf("sendThreadRunnner exception %s\n", ex.what()); + printf("sendThreadRunnner exception %s\n", ex.what()); // TODO } catch (...) { printf("sendThreadRunnner exception\n"); } diff --git a/pvAccessApp/remote/blockingUDPConnector.cpp b/pvAccessApp/remote/blockingUDPConnector.cpp index 248295d..b901408 100644 --- a/pvAccessApp/remote/blockingUDPConnector.cpp +++ b/pvAccessApp/remote/blockingUDPConnector.cpp @@ -10,7 +10,7 @@ #include /* EPICSv3 */ -#include +#include #include /* standard */ @@ -26,14 +26,14 @@ namespace epics { auto_ptr& responseHandler, osiSockAddr& bindAddress, short transportRevision, int16 priority) { - errlogSevPrintf(errlogInfo, "Creating datagram socket to: %s", + LOG(logLevelDebug, "Creating datagram socket to: %s", inetAddressToString(bindAddress).c_str()); SOCKET socket = epicsSocketCreate(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if(socket==INVALID_SOCKET) { char errStr[64]; epicsSocketConvertErrnoToString(errStr, sizeof(errStr)); - errlogSevPrintf(errlogMajor, "Error creating socket: %s", errStr); + LOG(logLevelError, "Error creating socket: %s", errStr); return Transport::shared_pointer(); } @@ -43,7 +43,7 @@ namespace epics { { char errStr[64]; epicsSocketConvertErrnoToString(errStr, sizeof(errStr)); - errlogSevPrintf(errlogMajor, "Error setting SO_BROADCAST: %s", errStr); + LOG(logLevelError, "Error setting SO_BROADCAST: %s", errStr); epicsSocketDestroy (socket); return Transport::shared_pointer(); } @@ -60,7 +60,7 @@ namespace epics { if(retval<0) { char errStr[64]; epicsSocketConvertErrnoToString(errStr, sizeof(errStr)); - errlogSevPrintf(errlogMajor, "Error binding socket: %s", errStr); + LOG(logLevelError, "Error binding socket: %s", errStr); epicsSocketDestroy (socket); return Transport::shared_pointer(); } diff --git a/pvAccessApp/remote/blockingUDPTransport.cpp b/pvAccessApp/remote/blockingUDPTransport.cpp index 3760392..2981fd6 100644 --- a/pvAccessApp/remote/blockingUDPTransport.cpp +++ b/pvAccessApp/remote/blockingUDPTransport.cpp @@ -18,7 +18,7 @@ /* EPICSv3 */ #include #include -#include +#include #include /* standard */ @@ -57,11 +57,11 @@ namespace epics { timeout.tv_sec = 1; timeout.tv_usec = 0; - if (setsockopt (_channel, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) < 0) + if (::setsockopt (_channel, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) < 0) { char errStr[64]; epicsSocketConvertErrnoToString(errStr, sizeof(errStr)); - errlogSevPrintf(errlogMajor, + LOG(logLevelError, "Failed to set SO_RCVTIMEO for UDP socket %s: %s.", inetAddressToString(_bindAddress).c_str(), errStr); } @@ -84,7 +84,7 @@ namespace epics { void BlockingUDPTransport::start() { String threadName = "UDP-receive "+inetAddressToString(_bindAddress); - errlogSevPrintf(errlogInfo, "Starting thread: %s",threadName.c_str()); + LOG(logLevelDebug, "Starting thread: %s",threadName.c_str()); _threadId = epicsThreadCreate(threadName.c_str(), epicsThreadPriorityMedium, @@ -102,7 +102,7 @@ namespace epics { if(_closed) return; _closed = true; - errlogSevPrintf(errlogInfo, + LOG(logLevelDebug, "UDP socket %s closed.", inetAddressToString(_bindAddress).c_str()); @@ -116,7 +116,7 @@ namespace epics { { if (!_shutdownEvent.wait(5.0)) { - errlogSevPrintf(errlogMajor, + LOG(logLevelError, "Receive thread for UDP socket %s has not exited.", inetAddressToString(_bindAddress).c_str()); } @@ -233,7 +233,7 @@ namespace epics { { char errStr[64]; epicsSocketConvertErrnoToString(errStr, sizeof(errStr)); - errlogSevPrintf(errlogMajor, "Socket recvfrom error: %s", errStr); + LOG(logLevelError, "Socket recvfrom error: %s", errStr); } close(true, false); @@ -248,7 +248,7 @@ namespace epics { char threadName[40]; epicsThreadGetName(_threadId, threadName, 40); - errlogSevPrintf(errlogInfo, "Thread '%s' exiting", threadName); + LOG(logLevelDebug, "Thread '%s' exiting", threadName); _shutdownEvent.signal(); } @@ -300,7 +300,7 @@ namespace epics { { char errStr[64]; epicsSocketConvertErrnoToString(errStr, sizeof(errStr)); - errlogSevPrintf(errlogMajor, "Socket sendto error: %s", errStr); + LOG(logLevelDebug, "Socket sendto error: %s", errStr); return false; } @@ -320,7 +320,7 @@ namespace epics { { char errStr[64]; epicsSocketConvertErrnoToString(errStr, sizeof(errStr)); - errlogSevPrintf(errlogMajor, "Socket sendto error: %s", errStr); + LOG(logLevelDebug, "Socket sendto error: %s", errStr); } return false; } @@ -342,7 +342,7 @@ namespace epics { { char errStr[64]; epicsSocketConvertErrnoToString(errStr, sizeof(errStr)); - errlogSevPrintf(errlogMajor, "Socket getsockopt SO_RCVBUF error: %s", errStr); + LOG(logLevelError, "Socket getsockopt SO_RCVBUF error: %s", errStr); } return sockBufSize; diff --git a/pvAccessApp/remote/channelSearchManager.cpp b/pvAccessApp/remote/channelSearchManager.cpp index f45f338..f3f4434 100644 --- a/pvAccessApp/remote/channelSearchManager.cpp +++ b/pvAccessApp/remote/channelSearchManager.cpp @@ -304,7 +304,7 @@ void SearchTimer::callback() { Lock guard(_volMutex); - _startSequenceNumber = _chanSearchManager->getSequenceNumber() + 1; + _startSequenceNumber = _chanSearchManager->getSequenceNumber(); _searchAttempts = 0; _searchRespones = 0; } @@ -337,6 +337,12 @@ void SearchTimer::callback() bool requestSent = true; bool allowNewFrame = (framesSent+1) < _framesPerTry; + + { + Lock guard(_volMutex); + _endSequenceNumber = _chanSearchManager->getSequenceNumber() + 1; + } + bool frameWasSent = _chanSearchManager->generateSearchRequestMessage(channel, allowNewFrame); if(frameWasSent) { @@ -392,6 +398,12 @@ void SearchTimer::callback() // flush out the search request buffer if(triesInFrame > 0) { + + { + Lock guard(_volMutex); + _endSequenceNumber = _chanSearchManager->getSequenceNumber() + 1; + } + _chanSearchManager->flushSendBuffer(); framesSent++; } @@ -400,6 +412,7 @@ void SearchTimer::callback() { Lock guard(_volMutex); _endSequenceNumber = _chanSearchManager->getSequenceNumber(); + //printf("[%d] sn %d -> %d\n", _timerIndex, _startSequenceNumber, _endSequenceNumber); // reschedule canceled = _canceled; @@ -424,8 +437,10 @@ void SearchTimer::searchResponse(int32 responseSequenceNumber, bool isSequenceNu if(isSequenceNumberValid) { - validResponse = _startSequenceNumber <= _chanSearchManager->getSequenceNumber() && _chanSearchManager->getSequenceNumber() <= _endSequenceNumber; + validResponse = _startSequenceNumber <= responseSequenceNumber && responseSequenceNumber <= _endSequenceNumber; } + //if (!validResponse) + // printf("[%d] not valid response %d < %d < %d\n", _timerIndex, _startSequenceNumber,responseSequenceNumber, _endSequenceNumber); } @@ -582,7 +597,7 @@ void ChannelSearchManager::searchResponse(int32 cid, int32 seqNo, int8 minorRevi now.getCurrent(); _timers[timerIndex]->searchResponse(seqNo, seqNo != 0, now.getMilliseconds()); - // then notify SearchInstance + // then noftify SearchInstance si->searchResponse(minorRevision, serverAddress); //si->release(); } diff --git a/pvAccessApp/remoteClient/clientContextImpl.cpp b/pvAccessApp/remoteClient/clientContextImpl.cpp index 81fc9f2..5b641bc 100644 --- a/pvAccessApp/remoteClient/clientContextImpl.cpp +++ b/pvAccessApp/remoteClient/clientContextImpl.cpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include using std::tr1::dynamic_pointer_cast; @@ -46,8 +46,8 @@ namespace epics { #define EXCEPTION_GUARD(code) try { code; } \ - catch (std::exception &e) { errlogSevPrintf(errlogMajor, "Unhandled exception caught from client code at %s:%d: %s", __FILE__, __LINE__, e.what()); } \ - catch (...) { errlogSevPrintf(errlogMajor, "Unhandled exception caught from client code at %s:%d.", __FILE__, __LINE__); } + catch (std::exception &e) { LOG(logLevelError, "Unhandled exception caught from client code at %s:%d: %s", __FILE__, __LINE__, e.what()); } \ + catch (...) { LOG(logLevelError, "Unhandled exception caught from client code at %s:%d.", __FILE__, __LINE__); } struct delayed_destroyable_deleter { @@ -211,9 +211,9 @@ namespace epics { } } catch (std::exception &e) { - errlogSevPrintf(errlogMajor, "Unhandled exception caught from client code at %s:%d: %s", __FILE__, __LINE__, e.what()); + LOG(logLevelError, "Unhandled exception caught from client code at %s:%d: %s", __FILE__, __LINE__, e.what()); } - catch (...) { errlogSevPrintf(errlogMajor, "Unhandled exception caught from client code at %s:%d.", __FILE__, __LINE__); + catch (...) { LOG(logLevelError, "Unhandled exception caught from client code at %s:%d.", __FILE__, __LINE__); } } @@ -2286,7 +2286,7 @@ namespace epics { char ipAddrStr[48]; ipAddrToDottedIP(&responseFrom->ia, ipAddrStr, sizeof(ipAddrStr)); - errlogSevPrintf(errlogInfo, + LOG(logLevelInfo, "Undecipherable message (bad response type %d) from %s.", command, ipAddrStr); } @@ -3207,7 +3207,7 @@ namespace epics { void disconnect(bool initiateSearch, bool remoteDestroy) { Lock guard(m_channelMutex); - if (m_connectionState != CONNECTED && !m_transport) + if (m_connectionState != CONNECTED) return; if (!initiateSearch) { @@ -4028,6 +4028,7 @@ TODO { try { + // TODO we are creating a new response handler even-though we might not need a new transprot !!! ClientContextImpl::shared_pointer thisPointer = shared_from_this(); auto_ptr handler(new ClientResponseHandler(thisPointer)); return m_connector->connect(client, handler, *serverAddress, minorRevision, priority); diff --git a/pvAccessApp/server/beaconEmitter.cpp b/pvAccessApp/server/beaconEmitter.cpp index 36710ce..921cc00 100644 --- a/pvAccessApp/server/beaconEmitter.cpp +++ b/pvAccessApp/server/beaconEmitter.cpp @@ -6,7 +6,7 @@ #include -#include +#include #include #include @@ -78,7 +78,7 @@ void BeaconEmitter::send(ByteBuffer* buffer, TransportSendControl* control) } catch (...) { // we have to proctect internal code from external implementation... - errlogSevPrintf(errlogMinor, "BeaconServerStatusProvider implementation thrown an exception."); + LOG(logLevelDebug, "BeaconServerStatusProvider implementation thrown an exception."); } } diff --git a/pvAccessApp/server/responseHandlers.cpp b/pvAccessApp/server/responseHandlers.cpp index 7d0ab95..4c294c8 100644 --- a/pvAccessApp/server/responseHandlers.cpp +++ b/pvAccessApp/server/responseHandlers.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include @@ -34,7 +34,7 @@ void ServerBadResponse::handleResponse(osiSockAddr* responseFrom, char ipAddrStr[48]; ipAddrToDottedIP(&responseFrom->ia, ipAddrStr, sizeof(ipAddrStr)); - errlogSevPrintf(errlogInfo, + LOG(logLevelInfo, "Undecipherable message (bad response type %d) from %s.", command, ipAddrStr); @@ -76,7 +76,7 @@ void ServerResponseHandler::handleResponse(osiSockAddr* responseFrom, { if(command<0||command>=(int8)m_handlerTable.size()) { - errlogSevPrintf(errlogMinor, + LOG(logLevelDebug, "Invalid (or unsupported) command: %x.", (0xFF&command)); // TODO remove debug output @@ -216,14 +216,14 @@ void ServerChannelFindRequesterImpl::channelFindResult(const Status& status, Cha { if ((_responseCount+1) == _expectedResponseCount) { - errlogSevPrintf(errlogMinor,"[ServerChannelFindRequesterImpl::channelFindResult] More responses received than expected fpr channel '%s'!", _name.c_str()); + LOG(logLevelDebug,"[ServerChannelFindRequesterImpl::channelFindResult] More responses received than expected fpr channel '%s'!", _name.c_str()); } return; } if (wasFound && _wasFound) { - errlogSevPrintf(errlogMinor,"[ServerChannelFindRequesterImpl::channelFindResult] Channel '%s' is hosted by different channel providers!", _name.c_str()); + LOG(logLevelDebug,"[ServerChannelFindRequesterImpl::channelFindResult] Channel '%s' is hosted by different channel providers!", _name.c_str()); return; } @@ -291,7 +291,7 @@ void ServerCreateChannelHandler::handleResponse(osiSockAddr* responseFrom, char host[100]; sockAddrToA(&transport->getRemoteAddress()->sa,host,100); - errlogSevPrintf(errlogMinor,"Zero length channel name, disconnecting client: %s", host); + LOG(logLevelDebug,"Zero length channel name, disconnecting client: %s", host); disconnect(transport); return; } @@ -299,7 +299,7 @@ void ServerCreateChannelHandler::handleResponse(osiSockAddr* responseFrom, { char host[100]; sockAddrToA(&transport->getRemoteAddress()->sa,host,100); - errlogSevPrintf(errlogMinor,"Unreasonable channel name length, disconnecting client: %s", host); + LOG(logLevelDebug,"Unreasonable channel name length, disconnecting client: %s", host); disconnect(transport); return; } @@ -385,7 +385,7 @@ void ServerChannelRequesterImpl::channelCreated(const Status& status, Channel::s } catch (std::exception& e) { - errlogSevPrintf(errlogMinor, "Exception caught when creating channel: %s", _channelName.c_str()); + LOG(logLevelDebug, "Exception caught when creating channel: %s", _channelName.c_str()); { Lock guard(_mutex); _status = Status(Status::STATUSTYPE_FATAL, "failed to create channel", e.what()); @@ -396,7 +396,7 @@ void ServerChannelRequesterImpl::channelCreated(const Status& status, Channel::s } catch (...) { - errlogSevPrintf(errlogMinor, "Exception caught when creating channel: %s", _channelName.c_str()); + LOG(logLevelDebug, "Exception caught when creating channel: %s", _channelName.c_str()); { Lock guard(_mutex); _status = Status(Status::STATUSTYPE_FATAL, "failed to create channel"); @@ -422,7 +422,7 @@ String ServerChannelRequesterImpl::getRequesterName() void ServerChannelRequesterImpl::message(const String message, const MessageType messageType) { - errlogSevPrintf(errlogMinor, "[%s] %s", messageTypeName[messageType].c_str(), message.c_str()); + LOG(logLevelDebug, "[%s] %s", messageTypeName[messageType].c_str(), message.c_str()); } void ServerChannelRequesterImpl::lock() @@ -498,7 +498,7 @@ void ServerDestroyChannelHandler::handleResponse(osiSockAddr* responseFrom, { char host[100]; sockAddrToA(&responseFrom->sa,host,100); - errlogSevPrintf(errlogMinor, "Trying to destroy a channel that no longer exists (SID: %d, CID %d, client: %s).", sid, cid, host); + LOG(logLevelDebug, "Trying to destroy a channel that no longer exists (SID: %d, CID %d, client: %s).", sid, cid, host); } return; } diff --git a/pvAccessApp/server/serverContext.cpp b/pvAccessApp/server/serverContext.cpp index 97e68ff..6f0f3d3 100644 --- a/pvAccessApp/server/serverContext.cpp +++ b/pvAccessApp/server/serverContext.cpp @@ -4,6 +4,7 @@ #include #include +#include using std::tr1::dynamic_pointer_cast; using std::tr1::static_pointer_cast; @@ -42,6 +43,10 @@ ServerContextImpl::ServerContextImpl(): _beaconServerStatusProvider() { + // TODO maybe there is a better place for this (when there will be some factory) + epicsSignalInstallSigAlarmIgnore (); + epicsSignalInstallSigPipeIgnore (); + initializeLogger(); loadConfiguration(); } @@ -372,7 +377,7 @@ void ServerContextImpl::destroyAllTransports() if (size == 0) return; - errlogSevPrintf(errlogInfo, "Server context still has %d transport(s) active and closing...", size); + LOG(logLevelInfo, "Server context still has %d transport(s) active and closing...", size); for (int i = 0; i < size; i++) { @@ -384,12 +389,12 @@ void ServerContextImpl::destroyAllTransports() catch (std::exception &e) { // do all exception safe, log in case of an error - errlogSevPrintf(errlogMajor, "Unhandled exception caught from client code at %s:%d: %s", __FILE__, __LINE__, e.what()); + LOG(logLevelError, "Unhandled exception caught from client code at %s:%d: %s", __FILE__, __LINE__, e.what()); } catch (...) { // do all exception safe, log in case of an error - errlogSevPrintf(errlogMajor, "Unhandled exception caught from client code at %s:%d.", __FILE__, __LINE__); + LOG(logLevelError, "Unhandled exception caught from client code at %s:%d.", __FILE__, __LINE__); } } diff --git a/pvAccessApp/server/serverContext.h b/pvAccessApp/server/serverContext.h index b775d0c..feba54c 100644 --- a/pvAccessApp/server/serverContext.h +++ b/pvAccessApp/server/serverContext.h @@ -15,7 +15,7 @@ #include #include -#include +#include namespace epics { namespace pvAccess { diff --git a/pvAccessApp/utils/inetAddressUtil.cpp b/pvAccessApp/utils/inetAddressUtil.cpp index b48523e..27eb580 100644 --- a/pvAccessApp/utils/inetAddressUtil.cpp +++ b/pvAccessApp/utils/inetAddressUtil.cpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include /* standard */ #include @@ -94,7 +94,7 @@ namespace epics { */ pIfreqList = new ifreq[nelem]; if(!pIfreqList) { - errlogSevPrintf(errlogMajor, + LOG(logLevelError, "getBroadcastAddresses(): no memory to complete request"); addDefaultBroadcastAddress(retVector, defaultPort); return retVector; @@ -106,7 +106,7 @@ namespace epics { memset(ifconf.ifc_req, 0, ifconf.ifc_len); status = ioctl(sock, SIOCGIFCONF, &ifconf); if(status<0||ifconf.ifc_len==0) { - errlogSevPrintf(errlogMinor, + LOG(logLevelDebug, "getBroadcastAddresses(): unable to fetch network interface configuration"); delete[] pIfreqList; addDefaultBroadcastAddress(retVector, defaultPort); @@ -138,8 +138,8 @@ namespace epics { sizeof(ifrBuff.ifr_name)); status = ioctl(sock, SIOCGIFFLAGS, &ifrBuff); if(status) { - errlogSevPrintf( - errlogMinor, + LOG( + logLevelDebug, "getBroadcastAddresses(): net intf flags fetch for \"%s\" failed", pifreq->ifr_name); continue; @@ -170,8 +170,8 @@ namespace epics { sizeof(ifrBuff.ifr_name)); status = ioctl(sock, SIOCGIFBRDADDR, &ifrBuff); if(status) { - errlogSevPrintf( - errlogMinor, + LOG( + logLevelDebug, "getBroadcastAddresses(): net intf \"%s\": bcast addr fetch fail", pifreq->ifr_name); continue; @@ -184,8 +184,8 @@ namespace epics { sizeof(ifrBuff.ifr_name)); status = ioctl(sock, SIOCGIFDSTADDR, &ifrBuff); if(status) { - errlogSevPrintf( - errlogMinor, + LOG( + logLevelDebug, "getBroadcastAddresses(): net intf \"%s\": pt to pt addr fetch fail", pifreq->ifr_name); continue; @@ -194,8 +194,8 @@ namespace epics { } #endif else { - errlogSevPrintf( - errlogMinor, + LOG( + logLevelDebug, "getBroadcastAddresses(): net intf \"%s\": not point to point or bcast?", pifreq->ifr_name); continue; diff --git a/pvAccessApp/utils/logger.cpp b/pvAccessApp/utils/logger.cpp index afb383f..0b0ef7e 100644 --- a/pvAccessApp/utils/logger.cpp +++ b/pvAccessApp/utils/logger.cpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include @@ -24,8 +24,43 @@ using std::ofstream; using std::ios; using std::endl; +#include + +#include + namespace epics { namespace pvAccess { + + #define TIMETEXTLEN 32 + + static pvAccessLogLevel g_pvAccessLogLevel = logLevelDebug; //logLevelInfo; + + void pvAccessLog(pvAccessLogLevel level, const char* format, ...) + { + // TODO lock + if (level >= g_pvAccessLogLevel) + { + char timeText[TIMETEXTLEN]; + epicsTimeStamp tsNow; + + epicsTimeGetCurrent(&tsNow); + epicsTimeToStrftime(timeText, TIMETEXTLEN, "%Y-%m-%dT%H:%M:%S.%03f", &tsNow); + + printf("%s ", timeText); + + va_list arg; + va_start(arg, format); + vprintf(format, arg); + va_end(arg); + + printf("\n"); + } + } + + void pvAccessSetLogLevel(pvAccessLogLevel level) + { + g_pvAccessLogLevel = level; + } class FileLogger : public NoDefaultMethods { public: diff --git a/pvAccessApp/utils/logger.h b/pvAccessApp/utils/logger.h index ee7abb3..4a74b47 100644 --- a/pvAccessApp/utils/logger.h +++ b/pvAccessApp/utils/logger.h @@ -10,9 +10,47 @@ #include +#include + namespace epics { namespace pvAccess { + + typedef enum { logLevelAll = 0, logLevelTrace, logLevelDebug, logLevelInfo, + logLevelWarn, logLevelError, logLevelFatal, logLevelOff } pvAccessLogLevel; + /* + ALL + The ALL has the lowest possible rank and is intended to turn on all logging. + TRACE + The TRACE Level designates finer-grained informational events than the DEBUG + DEBUG + The DEBUG Level designates fine-grained informational events that are most useful to debug an application. + INFO + The INFO level designates informational messages that highlight the progress of the application at coarse-grained level. + WARN + The WARN level designates potentially harmful situations. + ERROR + The ERROR level designates error events that might still allow the application to continue running. + FATAL + The FATAL level designates very severe error events that will presumably lead the application to abort. + OFF + The OFF has the highest possible rank and is intended to turn off logging. + */ + + void pvAccessLog(pvAccessLogLevel level, const char* format, ...); + void pvAccessSetLogLevel(pvAccessLogLevel level); + + #define LOG(level, format, ...) pvAccessLog(level, format, ##__VA_ARGS__) + #define SET_LOG_LEVEL(level) pvAccessSetLogLevel(level) + + // EPICS errlog + //#define LOG errlogSevPrintf + //#define SET_LOG_LEVEL(level) errlogSetSevToLog(level) + + // none + //#define LOG(level, fmt, ...) + //#define SET_LOG_LEVEL(level) + /** * Create a logger that will write to file indicated by the fname. * After creation you are free to use standard EPICSv3 functions from diff --git a/testApp/remote/Makefile b/testApp/remote/Makefile index 146ebab..4a7fc8f 100644 --- a/testApp/remote/Makefile +++ b/testApp/remote/Makefile @@ -14,6 +14,10 @@ PROD_HOST += testRemoteClientImpl testRemoteClientImpl_SRCS += testRemoteClientImpl.cpp testRemoteClientImpl_LIBS += pvData pvAccess Com +PROD_HOST += testChannelConnect +testChannelConnect_SRCS += testChannelConnect.cpp +testChannelConnect_LIBS += pvData pvAccess Com + #PROD_HOST += testBeaconEmitter testBeaconEmitter_SRCS += testBeaconEmitter.cpp testBeaconEmitter_LIBS += pvData pvAccess Com diff --git a/testApp/remote/pvget.cpp b/testApp/remote/pvget.cpp index 5859bbb..ec05faf 100644 --- a/testApp/remote/pvget.cpp +++ b/testApp/remote/pvget.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include @@ -559,8 +559,8 @@ int main (int argc, char *argv[]) return 1; } - // typedef enum {errlogInfo, errlogMinor, errlogMajor, errlogFatal} errlogSevEnum; - errlogSetSevToLog(errlogMajor); + // typedef enum {logLevelInfo, logLevelDebug, logLevelError, errlogFatal} errlogSevEnum; + SET_LOG_LEVEL(logLevelError); ClientFactory::start(); diff --git a/testApp/remote/pvput.cpp b/testApp/remote/pvput.cpp index d9f2563..ac179c3 100644 --- a/testApp/remote/pvput.cpp +++ b/testApp/remote/pvput.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include @@ -605,8 +605,8 @@ int main (int argc, char *argv[]) return 1; } - // typedef enum {errlogInfo, errlogMinor, errlogMajor, errlogFatal} errlogSevEnum; - errlogSetSevToLog(errlogMajor); + // typedef enum {logLevelInfo, logLevelDebug, logLevelError, errlogFatal} errlogSevEnum; + SET_LOG_LEVEL(logLevelError); ClientFactory::start(); diff --git a/testApp/remote/testBlockingTCPClnt.cpp b/testApp/remote/testBlockingTCPClnt.cpp index 18f8f97..59a1494 100644 --- a/testApp/remote/testBlockingTCPClnt.cpp +++ b/testApp/remote/testBlockingTCPClnt.cpp @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include @@ -86,16 +86,16 @@ public: virtual ~DummyTransportClient() { } virtual void transportUnresponsive() { - errlogSevPrintf(errlogInfo, "unresponsive"); + LOG(logLevelInfo, "unresponsive"); } virtual void transportResponsive(Transport::shared_pointer const & transport) { - errlogSevPrintf(errlogInfo, "responsive"); + LOG(logLevelInfo, "responsive"); } virtual void transportChanged() { - errlogSevPrintf(errlogInfo, "changed"); + LOG(logLevelInfo, "changed"); } virtual void transportClosed() { - errlogSevPrintf(errlogInfo, "closed"); + LOG(logLevelInfo, "closed"); } virtual void acquire() {}; virtual void release() {}; diff --git a/testApp/remote/testChannelConnect.cpp b/testApp/remote/testChannelConnect.cpp new file mode 100644 index 0000000..7b2002c --- /dev/null +++ b/testApp/remote/testChannelConnect.cpp @@ -0,0 +1,95 @@ + +/* testChannelConnect.cpp */ +/* Author: Matej Sekoranja Date: 2011.8.24 */ + + +#include +#include +#include +#include +#include +#include + +using namespace epics::pvData; +using namespace epics::pvAccess; + +#define N_CHANNELS 10000 + +static Event g_event; + +class ChannelRequesterImpl : public ChannelRequester +{ +public: + ChannelRequesterImpl() : count(0) {} +private: + int count; + + virtual String getRequesterName() + { + return "ChannelRequesterImpl"; + }; + + virtual void message(String message,MessageType messageType) + { + std::cout << "[" << getRequesterName() << "] message(" << message << ", " << messageTypeName[messageType] << ")" << std::endl; + } + + virtual void channelCreated(const epics::pvData::Status& status, Channel::shared_pointer const & channel) + { + if (!status.isSuccess()) + { + std::cout << "channelCreated(" << status.toString() << ", " + << (channel ? channel->getChannelName() : "(0)") << ")" << std::endl; + } + } + + // always called from the same thread + virtual void channelStateChange(Channel::shared_pointer const & c, Channel::ConnectionState connectionState) + { + if (connectionState == Channel::CONNECTED) + { + cout << c->getChannelName() << " CONNECTED: " << (count+1) << endl; + if (++count == N_CHANNELS) + g_event.signal(); + } + else if (connectionState == Channel::DISCONNECTED) + { + --count; + cout << c->getChannelName() << " DISCONNECTED: " << count << endl; + } + else + cout << c->getChannelName() << " " << Channel::ConnectionStateNames[connectionState] << endl; + + } +}; + + + +int main(int argc,char *argv[]) +{ + { + ClientFactory::start(); + ChannelProvider::shared_pointer provider = getChannelAccess()->getProvider("pvAccess"); + ChannelRequester::shared_pointer channelRequester(new ChannelRequesterImpl()); + + Channel::shared_pointer channels[N_CHANNELS]; + char buf[16]; + for (int i = 0; i < N_CHANNELS; i++) + { + sprintf(buf, "record%d", (i+1)); + channels[i] = provider->createChannel(buf, channelRequester); + } + + g_event.wait(); + + cout << "connected to all" << endl; + + ClientFactory::stop(); + } + + epicsThreadSleep ( 1.0 ); + std::cout << "-----------------------------------------------------------------------" << std::endl; + epicsExitCallAtExits(); + CDRMonitor::get().show(stdout); + return(0); +} diff --git a/testApp/utils/loggerTest.cpp b/testApp/utils/loggerTest.cpp index 453aac6..bddff7b 100644 --- a/testApp/utils/loggerTest.cpp +++ b/testApp/utils/loggerTest.cpp @@ -7,7 +7,7 @@ #include -#include +#include #include #include @@ -19,10 +19,10 @@ int main(int argc, char *argv[]) { createFileLogger("loggerTest.log"); - errlogSetSevToLog(errlogMinor); - errlogSevPrintf( errlogInfo, "This will not appear"); - errlogSevPrintf( errlogMajor, "This is a test %d", 42); - errlogSevPrintf( errlogFatal, "This is another test %f", 3.14); + SET_LOG_LEVEL(logLevelDebug); + LOG( logLevelInfo, "This will not appear"); + LOG( logLevelError, "This is a test %d", 42); + LOG( logLevelFatal, "This is another test %f", 3.14); epicsExit(0); }