This commit is contained in:
mrkraimer
2018-01-30 05:35:00 -05:00
14 changed files with 81 additions and 167 deletions
+1 -1
View File
@@ -250,7 +250,7 @@ bool discoverServers(double timeOut)
for (size_t i = 0; i < broadcastAddresses.size(); i++)
LOG(logLevelDebug,
"Broadcast address #%d: %s.", i, inetAddressToString(broadcastAddresses[i]).c_str());
"Broadcast address #%zu: %s.", i, inetAddressToString(broadcastAddresses[i]).c_str());
// ---
+1 -27
View File
@@ -11,35 +11,9 @@
/* Author: Marty Kraimer */
#include <cstddef>
#include <cstdlib>
#include <cstddef>
#include <string>
#include <cstdio>
#include <memory>
#include <iostream>
#include <iocsh.h>
#include <epicsExit.h>
#include <pv/pvAccess.h>
#include <pv/clientFactory.h>
#include <epicsExport.h>
using namespace epics::pvAccess;
static void stopPVAClient(void*)
{
ClientFactory::stop();
}
static void registerStartPVAClient(void)
{
ClientFactory::start();
epicsAtExit(stopPVAClient, 0);
}
static void registerStartPVAClient(void) {}
extern "C" {
epicsExportRegistrar(registerStartPVAClient);
+6 -1
View File
@@ -103,10 +103,16 @@ void pvasr(int lvl)
}
}
void pva_server_cleanup(void *)
{
stopPVAServer();
}
void initStartPVAServer(initHookState state)
{
pvd::Lock G(the_server_lock);
if(state==initHookAfterIocRunning && !the_server) {
epicsAtExit(&pva_server_cleanup, 0);
startitup();
} else if(state==initHookAtIocPause) {
@@ -114,7 +120,6 @@ void initStartPVAServer(initHookState state)
}
}
void registerStartPVAServer(void)
{
epics::iocshRegister<const char*, &startPVAServer>("startPVAServer", "provider names");
-3
View File
@@ -33,9 +33,6 @@ BlockingTCPConnector::BlockingTCPConnector(
{
}
BlockingTCPConnector::~BlockingTCPConnector() {
}
SOCKET BlockingTCPConnector::tryConnect(osiSockAddr& address, int tries) {
char strBuffer[64];
+9 -10
View File
@@ -18,9 +18,9 @@ using namespace epics::pvData;
namespace {
struct closer {
epics::pvAccess::Transport::shared_pointer P;
closer(const epics::pvAccess::Transport::shared_pointer& P) :P(P) {}
void operator()(epics::pvAccess::Transport*) {
epics::pvAccess::BlockingUDPTransport::shared_pointer P;
closer(const epics::pvAccess::BlockingUDPTransport::shared_pointer& P) :P(P) {}
void operator()(epics::pvAccess::BlockingUDPTransport*) {
try{
P->close();
}catch(...){
@@ -35,7 +35,7 @@ struct closer {
namespace epics {
namespace pvAccess {
Transport::shared_pointer BlockingUDPConnector::connect(std::tr1::shared_ptr<ClientChannelImpl> const & /*client*/,
BlockingUDPTransport::shared_pointer BlockingUDPConnector::connect(std::tr1::shared_ptr<ClientChannelImpl> const & /*client*/,
ResponseHandler::shared_pointer const & responseHandler, osiSockAddr& bindAddress,
int8 transportRevision, int16 /*priority*/) {
@@ -47,7 +47,7 @@ Transport::shared_pointer BlockingUDPConnector::connect(std::tr1::shared_ptr<Cli
char errStr[64];
epicsSocketConvertErrnoToString(errStr, sizeof(errStr));
LOG(logLevelError, "Error creating socket: %s.", errStr);
return Transport::shared_pointer();
return BlockingUDPTransport::shared_pointer();
}
int optval = _broadcast ? 1 : 0;
@@ -58,7 +58,7 @@ Transport::shared_pointer BlockingUDPConnector::connect(std::tr1::shared_ptr<Cli
epicsSocketConvertErrnoToString(errStr, sizeof(errStr));
LOG(logLevelError, "Error setting SO_BROADCAST: %s.", errStr);
epicsSocketDestroy (socket);
return Transport::shared_pointer();
return BlockingUDPTransport::shared_pointer();
}
/*
@@ -83,17 +83,16 @@ Transport::shared_pointer BlockingUDPConnector::connect(std::tr1::shared_ptr<Cli
epicsSocketConvertErrnoToString(errStr, sizeof(errStr));
LOG(logLevelError, "Error binding socket %s: %s.", ip, errStr);
epicsSocketDestroy (socket);
return Transport::shared_pointer();
return BlockingUDPTransport::shared_pointer();
}
// sockets are blocking by default
BlockingUDPTransport::shared_pointer transport(new BlockingUDPTransport(_serverFlag, responseHandler,
socket, bindAddress, transportRevision));
transport->internal_this = transport;
// the worker thread holds a strong ref, which is released by transport->close()
// note: casting to Transport* to prevent iOS version of shared_ptr from trying (and failing)
// to setup shared_from_this() using the wrapped pointer
Transport::shared_pointer ret(static_cast<Transport*>(transport.get()), closer(transport));
BlockingUDPTransport::shared_pointer ret(transport.get(), closer(transport));
return ret;
}
+14 -14
View File
@@ -207,7 +207,7 @@ void BlockingUDPTransport::run() {
osiSockAddr fromAddress;
osiSocklen_t addrStructSize = sizeof(sockaddr);
Transport::shared_pointer thisTransport = shared_from_this();
Transport::shared_pointer thisTransport(internal_this);
try {
@@ -395,7 +395,7 @@ bool BlockingUDPTransport::send(const char* buffer, size_t length, const osiSock
{
if (IS_LOGGABLE(logLevelDebug))
{
LOG(logLevelDebug, "Sending %d bytes to %s.",
LOG(logLevelDebug, "Sending %zu bytes to %s.",
length, inetAddressToString(address).c_str());
}
@@ -419,7 +419,7 @@ bool BlockingUDPTransport::send(ByteBuffer* buffer, const osiSockAddr& address)
if (IS_LOGGABLE(logLevelDebug))
{
LOG(logLevelDebug, "Sending %d bytes to %s.",
LOG(logLevelDebug, "Sending %zu bytes to %s.",
buffer->getRemaining(), inetAddressToString(address).c_str());
}
@@ -456,7 +456,7 @@ bool BlockingUDPTransport::send(ByteBuffer* buffer, InetAddressType target) {
if (IS_LOGGABLE(logLevelDebug))
{
LOG(logLevelDebug, "Sending %d bytes to %s.",
LOG(logLevelDebug, "Sending %zu bytes to %s.",
buffer->getRemaining(), inetAddressToString(_sendAddresses[i]).c_str());
}
@@ -573,10 +573,10 @@ void initializeUDPTransports(bool serverFlag,
anyAddress.ia.sin_port = htons(0);
anyAddress.ia.sin_addr.s_addr = htonl(INADDR_ANY);
sendTransport = static_pointer_cast<BlockingUDPTransport>(connector->connect(
sendTransport = connector->connect(
nullTransportClient, responseHandler,
anyAddress, PVA_PROTOCOL_REVISION,
PVA_DEFAULT_PRIORITY));
PVA_DEFAULT_PRIORITY);
if (!sendTransport)
{
THROW_BASE_EXCEPTION("Failed to initialize UDP transport.");
@@ -586,7 +586,7 @@ void initializeUDPTransports(bool serverFlag,
if (listenPort == 0)
{
listenPort = ntohs(sendTransport->getRemoteAddress()->ia.sin_port);
LOG(logLevelDebug, "Dynamic listen UDP port set to %d.", listenPort);
LOG(logLevelDebug, "Dynamic listen UDP port set to %u.", (unsigned)listenPort);
}
// TODO current implementation shares the port (aka beacon and search port)
@@ -651,7 +651,7 @@ void initializeUDPTransports(bool serverFlag,
else
for (size_t i = 0; i < blist.size(); i++)
LOG(logLevelDebug,
"Broadcast address #%d: %s.", i, inetAddressToString(blist[i]).c_str());
"Broadcast address #%zu: %s.", i, inetAddressToString(blist[i]).c_str());
// TODO configurable local NIF, address
@@ -693,10 +693,10 @@ void initializeUDPTransports(bool serverFlag,
listenLocalAddress.ia.sin_port = htons(listenPort);
listenLocalAddress.ia.sin_addr.s_addr = node.ifaceAddr.ia.sin_addr.s_addr;
BlockingUDPTransport::shared_pointer transport = static_pointer_cast<BlockingUDPTransport>(connector->connect(
BlockingUDPTransport::shared_pointer transport = connector->connect(
nullTransportClient, responseHandler,
listenLocalAddress, PVA_PROTOCOL_REVISION,
PVA_DEFAULT_PRIORITY));
PVA_DEFAULT_PRIORITY);
if (!transport)
continue;
listenLocalAddress = *transport->getRemoteAddress();
@@ -730,10 +730,10 @@ void initializeUDPTransports(bool serverFlag,
bcastAddress.ia.sin_port = htons(listenPort);
bcastAddress.ia.sin_addr.s_addr = node.ifaceBCast.ia.sin_addr.s_addr;
transport2 = static_pointer_cast<BlockingUDPTransport>(connector->connect(
transport2 = connector->connect(
nullTransportClient, responseHandler,
bcastAddress, PVA_PROTOCOL_REVISION,
PVA_DEFAULT_PRIORITY));
PVA_DEFAULT_PRIORITY);
if (transport2)
{
/* The other wrinkle is that nothing should be sent from this second
@@ -786,7 +786,7 @@ void initializeUDPTransports(bool serverFlag,
try
{
// NOTE: multicast receiver socket must be "bound" to INADDR_ANY or multicast address
localMulticastTransport = static_pointer_cast<BlockingUDPTransport>(connector->connect(
localMulticastTransport = connector->connect(
nullTransportClient, responseHandler,
#if !defined(_WIN32)
group,
@@ -794,7 +794,7 @@ void initializeUDPTransports(bool serverFlag,
anyAddress,
#endif
PVA_PROTOCOL_REVISION,
PVA_DEFAULT_PRIORITY));
PVA_DEFAULT_PRIORITY);
if (!localMulticastTransport)
throw std::runtime_error("Failed to bind UDP socket.");
+3 -3
View File
@@ -1569,7 +1569,7 @@ void BlockingServerTCPTransportCodec::destroyAllChannels() {
{
LOG(
logLevelDebug,
"Transport to %s still has %zd channel(s) active and closing...",
"Transport to %s still has %zu channel(s) active and closing...",
_socketName.c_str(), _channels.size());
}
@@ -1600,7 +1600,7 @@ void BlockingServerTCPTransportCodec::authenticationCompleted(epics::pvData::Sta
string errorMessage = "Re-authentication failed: " + status.getMessage();
if (!status.getStackDump().empty())
errorMessage += "\n" + status.getStackDump();
LOG(logLevelInfo, errorMessage.c_str());
LOG(logLevelInfo, "%s", errorMessage.c_str());
close();
}
@@ -1793,7 +1793,7 @@ void BlockingClientTCPTransportCodec::closedNotifyClients() {
{
LOG(
logLevelDebug,
"Transport to %s still has %d client(s) active and closing...",
"Transport to %s still has %zu client(s) active and closing...",
_socketName.c_str(), refs);
}
+2 -4
View File
@@ -49,16 +49,14 @@ class ClientChannelImpl;
* @author <a href="mailto:matej.sekoranjaATcosylab.com">Matej Sekoranja</a>
* @version $Id: BlockingTCPConnector.java,v 1.1 2010/05/03 14:45:47 mrkraimer Exp $
*/
class BlockingTCPConnector : public Connector {
class BlockingTCPConnector {
public:
POINTER_DEFINITIONS(BlockingTCPConnector);
BlockingTCPConnector(Context::shared_pointer const & context, int receiveBufferSize,
float beaconInterval);
virtual ~BlockingTCPConnector();
virtual Transport::shared_pointer connect(std::tr1::shared_ptr<ClientChannelImpl> const & client,
Transport::shared_pointer connect(std::tr1::shared_ptr<ClientChannelImpl> const & client,
ResponseHandler::shared_pointer const & responseHandler, osiSockAddr& address,
epics::pvData::int8 transportRevision, epics::pvData::int16 priority);
private:
+41 -65
View File
@@ -44,13 +44,13 @@ enum InetAddressType { inetAddressType_all, inetAddressType_unicast, inetAddress
class BlockingUDPTransport : public epics::pvData::NoDefaultMethods,
public Transport,
public TransportSendControl,
public std::tr1::enable_shared_from_this<BlockingUDPTransport>,
public epicsThreadRunable
{
public:
POINTER_DEFINITIONS(BlockingUDPTransport);
private:
std::tr1::weak_ptr<BlockingUDPTransport> internal_this;
friend class BlockingUDPConnector;
BlockingUDPTransport(bool serverFlag,
ResponseHandler::shared_pointer const & responseHandler,
@@ -58,99 +58,79 @@ private:
short remoteTransportRevision);
public:
static shared_pointer create(bool serverFlag,
ResponseHandler::shared_pointer const & responseHandler,
SOCKET channel, osiSockAddr& bindAddress,
short remoteTransportRevision) EPICS_DEPRECATED
{
shared_pointer thisPointer(
new BlockingUDPTransport(serverFlag, responseHandler,
channel, bindAddress,
remoteTransportRevision)
);
return thisPointer;
}
virtual ~BlockingUDPTransport();
virtual bool isClosed() {
virtual bool isClosed() OVERRIDE FINAL {
return _closed.get();
}
/*
void setReplyTransport(const Transport::shared_pointer& T)
{
_replyTransport = T;
}
*/
virtual const osiSockAddr* getRemoteAddress() const {
virtual const osiSockAddr* getRemoteAddress() const OVERRIDE FINAL {
return &_remoteAddress;
}
virtual const std::string& getRemoteName() const {
virtual const std::string& getRemoteName() const OVERRIDE FINAL {
return _remoteName;
}
virtual std::string getType() const {
virtual std::string getType() const OVERRIDE FINAL {
return std::string("udp");
}
virtual std::size_t getReceiveBufferSize() const {
virtual std::size_t getReceiveBufferSize() const OVERRIDE FINAL {
return _receiveBuffer.getSize();
}
virtual std::size_t getSocketReceiveBufferSize() const;
virtual std::size_t getSocketReceiveBufferSize() const OVERRIDE FINAL;
virtual epics::pvData::int16 getPriority() const {
virtual epics::pvData::int16 getPriority() const OVERRIDE FINAL {
return PVA_DEFAULT_PRIORITY;
}
virtual epics::pvData::int8 getRevision() const {
virtual epics::pvData::int8 getRevision() const OVERRIDE FINAL {
return PVA_PROTOCOL_REVISION;
}
virtual void setRemoteRevision(epics::pvData::int8 /*revision*/) {
virtual void setRemoteRevision(epics::pvData::int8 /*revision*/) OVERRIDE FINAL {
// noop
}
virtual void setRemoteTransportReceiveBufferSize(
std::size_t /*receiveBufferSize*/) {
std::size_t /*receiveBufferSize*/) OVERRIDE FINAL {
// noop for UDP (limited by 64k; MAX_UDP_SEND for PVA)
}
virtual void setRemoteTransportSocketReceiveBufferSize(
std::size_t /*socketReceiveBufferSize*/) {
std::size_t /*socketReceiveBufferSize*/) OVERRIDE FINAL {
// noop for UDP (limited by 64k; MAX_UDP_SEND for PVA)
}
virtual void aliveNotification() {
virtual void aliveNotification() OVERRIDE FINAL {
// noop
}
virtual void changedTransport() {
virtual void changedTransport() OVERRIDE FINAL {
// noop
}
virtual bool verify(epics::pvData::int32 /*timeoutMs*/) {
virtual bool verify(epics::pvData::int32 /*timeoutMs*/) OVERRIDE FINAL {
// noop
return true;
}
virtual void verified(epics::pvData::Status const & /*status*/) {
virtual void verified(epics::pvData::Status const & /*status*/) OVERRIDE FINAL {
// noop
}
virtual void authNZMessage(epics::pvData::PVField::shared_pointer const & data) {
virtual void authNZMessage(epics::pvData::PVField::shared_pointer const & data) OVERRIDE FINAL {
// noop
}
virtual std::tr1::shared_ptr<SecuritySession> getSecuritySession() const {
virtual std::tr1::shared_ptr<SecuritySession> getSecuritySession() const OVERRIDE FINAL {
return std::tr1::shared_ptr<SecuritySession>();
}
// NOTE: this is not yet used for UDP
virtual void setByteOrder(int byteOrder) {
virtual void setByteOrder(int byteOrder) OVERRIDE FINAL {
// called from receive thread... or before processing
_receiveBuffer.setEndianess(byteOrder);
@@ -158,93 +138,93 @@ public:
_sendBuffer.setEndianess(byteOrder);
}
virtual void enqueueSendRequest(TransportSender::shared_pointer const & sender);
virtual void enqueueSendRequest(TransportSender::shared_pointer const & sender) OVERRIDE FINAL;
virtual void flushSendQueue();
virtual void flushSendQueue() OVERRIDE FINAL;
void start();
virtual void close();
virtual void close() OVERRIDE FINAL;
virtual void ensureData(std::size_t size) {
virtual void ensureData(std::size_t size) OVERRIDE FINAL {
if (_receiveBuffer.getRemaining() < size)
throw std::underflow_error("no more data in UDP packet");
}
virtual void alignData(std::size_t alignment) {
virtual void alignData(std::size_t alignment) OVERRIDE FINAL {
_receiveBuffer.align(alignment);
}
virtual bool directSerialize(epics::pvData::ByteBuffer* /*existingBuffer*/, const char* /*toSerialize*/,
std::size_t /*elementCount*/, std::size_t /*elementSize*/)
std::size_t /*elementCount*/, std::size_t /*elementSize*/) OVERRIDE FINAL
{
return false;
}
virtual bool directDeserialize(epics::pvData::ByteBuffer* /*existingBuffer*/, char* /*deserializeTo*/,
std::size_t /*elementCount*/, std::size_t /*elementSize*/)
std::size_t /*elementCount*/, std::size_t /*elementSize*/) OVERRIDE FINAL
{
return false;
}
virtual void startMessage(epics::pvData::int8 command, std::size_t ensureCapacity, epics::pvData::int32 payloadSize = 0);
virtual void endMessage();
virtual void startMessage(epics::pvData::int8 command, std::size_t ensureCapacity, epics::pvData::int32 payloadSize = 0) OVERRIDE FINAL;
virtual void endMessage() OVERRIDE FINAL;
virtual void flush(bool /*lastMessageCompleted*/) {
virtual void flush(bool /*lastMessageCompleted*/) OVERRIDE FINAL {
// noop since all UDP requests are sent immediately
}
virtual void setRecipient(const osiSockAddr& sendTo) {
virtual void setRecipient(const osiSockAddr& sendTo) OVERRIDE FINAL {
_sendToEnabled = true;
_sendTo = sendTo;
}
virtual void setLocalMulticastAddress(const osiSockAddr& sendTo) {
void setLocalMulticastAddress(const osiSockAddr& sendTo) {
_localMulticastAddressEnabled = true;
_localMulticastAddress = sendTo;
}
virtual bool hasLocalMulticastAddress() const {
bool hasLocalMulticastAddress() const {
return _localMulticastAddressEnabled;
}
virtual const osiSockAddr& getLocalMulticastAddress() const {
const osiSockAddr& getLocalMulticastAddress() const {
return _localMulticastAddress;
}
virtual void flushSerializeBuffer() {
virtual void flushSerializeBuffer() OVERRIDE FINAL {
// noop
}
virtual void ensureBuffer(std::size_t /*size*/) {
virtual void ensureBuffer(std::size_t /*size*/) OVERRIDE FINAL {
// noop
}
virtual void alignBuffer(std::size_t alignment) {
virtual void alignBuffer(std::size_t alignment) OVERRIDE FINAL {
_sendBuffer.align(alignment);
}
virtual void cachedSerialize(
const std::tr1::shared_ptr<const epics::pvData::Field>& field, epics::pvData::ByteBuffer* buffer)
const std::tr1::shared_ptr<const epics::pvData::Field>& field, epics::pvData::ByteBuffer* buffer) OVERRIDE FINAL
{
// no cache
field->serialize(buffer, this);
}
virtual std::tr1::shared_ptr<const epics::pvData::Field>
cachedDeserialize(epics::pvData::ByteBuffer* buffer)
cachedDeserialize(epics::pvData::ByteBuffer* buffer) OVERRIDE FINAL
{
// no cache
// TODO
return epics::pvData::getFieldCreate()->deserialize(buffer, this);
}
virtual bool acquire(std::tr1::shared_ptr<ClientChannelImpl> const & /*client*/)
virtual bool acquire(std::tr1::shared_ptr<ClientChannelImpl> const & /*client*/) OVERRIDE FINAL
{
return false;
}
virtual void release(pvAccessID /*clientId*/) {}
virtual void release(pvAccessID /*clientId*/) OVERRIDE FINAL {}
/**
* Set ignore list.
@@ -428,7 +408,6 @@ private:
};
class BlockingUDPConnector :
public Connector,
private epics::pvData::NoDefaultMethods {
public:
POINTER_DEFINITIONS(BlockingUDPConnector);
@@ -442,13 +421,10 @@ public:
_broadcast(broadcast) {
}
virtual ~BlockingUDPConnector() {
}
/**
* NOTE: transport client is ignored for broadcast (UDP).
*/
virtual Transport::shared_pointer connect(std::tr1::shared_ptr<ClientChannelImpl> const & client,
BlockingUDPTransport::shared_pointer connect(std::tr1::shared_ptr<ClientChannelImpl> const & client,
ResponseHandler::shared_pointer const & responseHandler, osiSockAddr& bindAddress,
epics::pvData::int8 transportRevision, epics::pvData::int16 priority);
-22
View File
@@ -377,28 +377,6 @@ protected:
epics::pvData::int32 _debugLevel;
};
/**
* Interface defining socket connector (Connector-Transport pattern).
*/
class Connector {
public:
virtual ~Connector() {}
/**
* Connect.
* @param[in] client client requesting connection (transport).
* @param[in] address address of the server.
* @param[in] responseHandler reponse handler.
* @param[in] transportRevision transport revision to be used.
* @param[in] priority process priority.
* @return transport instance.
*/
virtual Transport::shared_pointer connect(std::tr1::shared_ptr<ClientChannelImpl> const & client,
ResponseHandler::shared_pointer const & responseHandler, osiSockAddr& address,
epics::pvData::int8 transportRevision, epics::pvData::int16 priority) = 0;
};
/**
* A request that expects an response.
* Responses identified by its I/O ID.
+1 -1
View File
@@ -4230,7 +4230,7 @@ private:
}
if (transportCount)
LOG(logLevelDebug, "PVA client context destroyed with %d transport(s) active.", transportCount);
LOG(logLevelDebug, "PVA client context destroyed with %u transport(s) active.", (unsigned)transportCount);
}
void destroyAllChannels() {
+1 -1
View File
@@ -369,7 +369,7 @@ void ServerContextImpl::destroyAllTransports()
if (size == 0)
return;
LOG(logLevelDebug, "Server context still has %d transport(s) active and closing...", size);
LOG(logLevelDebug, "Server context still has %zu transport(s) active and closing...", size);
for (size_t i = 0; i < size; i++)
{
+2 -1
View File
@@ -9,6 +9,7 @@
#include <string>
#include <compilerDependencies.h>
#include <shareLib.h>
namespace epics {
@@ -37,7 +38,7 @@ OFF
*/
epicsShareFunc void pvAccessLog(pvAccessLogLevel level, const char* format, ...);
epicsShareFunc void pvAccessLog(pvAccessLogLevel level, const char* format, ...) EPICS_PRINTF_STYLE(2, 3);
epicsShareFunc void pvAccessSetLogLevel(pvAccessLogLevel level);
epicsShareFunc bool pvAccessIsLoggable(pvAccessLogLevel level);
-14
View File
@@ -32,20 +32,6 @@ void setenv(char * a, char * b, int c)
using namespace epics::pvAccess;
using namespace epics::pvData;
static const char indata[] =
"hello = world \n"
" # oops\n"
" #dd=da\n"
" empty = \n"
" this = is a test\n\n"
;
static const char expectdata[] =
"empty = \n"
"hello = world\n"
"this = is a test\n"
;
static void showEnv(const char *name)
{
testDiag("%s = \"%s\"", name, getenv(name));