From 93196e63148b141fe169c233ff1d299ed5a5037d Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Mon, 19 Mar 2018 09:29:25 -0700 Subject: [PATCH 1/7] drop rtemsConfig.c no longer needed. --- testApp/Makefile | 2 +- testApp/rtemsConfig.c | 72 ---------- testApp/rtemsNetworking.h | 295 -------------------------------------- 3 files changed, 1 insertion(+), 368 deletions(-) delete mode 100644 testApp/rtemsConfig.c delete mode 100644 testApp/rtemsNetworking.h diff --git a/testApp/Makefile b/testApp/Makefile index 8a254a7..4d59b61 100644 --- a/testApp/Makefile +++ b/testApp/Makefile @@ -27,7 +27,7 @@ TESTSPEC_vxWorks = pvaTestHarness.$(MUNCH_SUFFIX); pvAccessAllTests # Build for RTEMS, with harness code & configuration PROD_RTEMS += pvaTestHarness -pvaTestHarness_SRCS_RTEMS += rtemsTestHarness.c rtemsConfig.c +pvaTestHarness_SRCS_RTEMS += rtemsTestHarness.c TESTSPEC_RTEMS = pvaTestHarness.$(MUNCH_SUFFIX); pvAccessAllTests # Build test scripts for hosts diff --git a/testApp/rtemsConfig.c b/testApp/rtemsConfig.c deleted file mode 100644 index ac3059f..0000000 --- a/testApp/rtemsConfig.c +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS configuration for EPICS - * Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd - * Author: W. Eric Norum - * norume@aps.anl.gov - * (630) 252-4793 - */ - -#include - -/* - *********************************************************************** - * RTEMS CONFIGURATION * - *********************************************************************** - */ -#define CONFIGURE_RTEMS_INIT_TASKS_TABLE - -#if __RTEMS_MAJOR__>4 || (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>9) || (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==9 && __RTEMS_REVISION__==99) -# define CONFIGURE_UNIFIED_WORK_AREAS -#else -# define CONFIGURE_EXECUTIVE_RAM_SIZE (2000*1024) -#endif - -#define CONFIGURE_MAXIMUM_TASKS rtems_resource_unlimited(30) -#define CONFIGURE_MAXIMUM_SEMAPHORES rtems_resource_unlimited(500) -#define CONFIGURE_MAXIMUM_TIMERS rtems_resource_unlimited(20) -#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES rtems_resource_unlimited(5) -#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1 - -#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 150 -#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM -#define CONFIGURE_MAXIMUM_DRIVERS 8 - -#define CONFIGURE_MICROSECONDS_PER_TICK 20000 - -#define CONFIGURE_INIT_TASK_PRIORITY 80 - -#define CONFIGURE_MALLOC_STATISTICS 1 - -#define CONFIGURE_INIT -#define CONFIGURE_INIT_TASK_INITIAL_MODES (RTEMS_PREEMPT | \ - RTEMS_NO_TIMESLICE | \ - RTEMS_NO_ASR | \ - RTEMS_INTERRUPT_LEVEL(0)) -#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_FLOATING_POINT | RTEMS_LOCAL) -#define CONFIGURE_INIT_TASK_STACK_SIZE (16*1024) -rtems_task Init (rtems_task_argument argument); - -#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER -#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER - -#define CONFIGURE_FILESYSTEM_NFS -#define CONFIGURE_FILESYSTEM_IMFS - -/* - * This should be made BSP dependent, not CPU dependent but I know of no - * appropriate conditionals to use. - * The new general time support makes including the RTC driverr less important. - */ -#if !defined(mpc604) && !defined(__mc68040__) && !defined(__mcf5200__) && !defined(mpc7455) && !defined(__arm__) /* don't have RTC code */ -#define CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER -#endif - - -#include -#include diff --git a/testApp/rtemsNetworking.h b/testApp/rtemsNetworking.h deleted file mode 100644 index f96cdbd..0000000 --- a/testApp/rtemsNetworking.h +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Network configuration -- QEMU NOT using DHCP - * - ************************************************************ - * EDIT THIS FILE TO REFLECT YOUR NETWORK CONFIGURATION * - * BEFORE RUNNING ANY RTEMS PROGRAMS WHICH USE THE NETWORK! * - ************************************************************ - * - * The dynamic probing is based upon the EPICS network - * configuration file written by: - * W. Eric Norum - * eric.norum@usask.ca - * (306) 966-5394 - */ - -#ifndef _RTEMS_NETWORKCONFIG_H_ -#define _RTEMS_NETWORKCONFIG_H_ - -/* #define USE_LIBBSDPORT */ - -#if defined(USE_LIBBSDPORT) -#include -#define CONFIGURE_MAXIMUM_TIMERS 10 -#endif -/* - * For TFTP test application - */ -#if (defined (RTEMS_USE_BOOTP)) -#define RTEMS_TFTP_TEST_HOST_NAME "BOOTP_HOST" -#define RTEMS_TFTP_TEST_FILE_NAME "BOOTP_FILE" -#else -#define RTEMS_TFTP_TEST_HOST_NAME "XXX.YYY.ZZZ.XYZ" -#define RTEMS_TFTP_TEST_FILE_NAME "tftptest" -#endif - -/* - * For NFS test application - * - * NFS mount and a directory to ls once mounted - */ -#define RTEMS_NFS_SERVER "192.168.1.210" -#define RTEMS_NFS_SERVER_PATH "/home" -#define RTEMS_NFS_LS_PATH "/mnt/nfstest" - - - -/* - * This file can be copied to an application source dirctory - * and modified to override the values shown below. - * - * The following CPP symbols may be passed from the Makefile: - * - * symbol default description - * - * NETWORK_TASK_PRIORITY 150 can be read by app from public - * var 'gesysNetworkTaskPriority' - * FIXED_IP_ADDR hardcoded IP address (e.g., - * "192.168.0.10"); disables BOOTP; - * must also define FIXED_NETMASK - * FIXED_NETMASK IP netmask string - * (e.g. "255.255.255.0") - * MULTI_NETDRIVER ugly hack; if defined try to probe - * a variety of PCI and ISA drivers - * (i386 ONLY) use is discouraged! - * NIC_NAME Ethernet driver name (e.g. "pcn1"); - * must also define NIC_ATTACH - * NIC_ATTACH Ethernet driver attach function - * (e.g., rtems_fxp_attach). - * If these are undefined then - * a) MULTI_NETDRIVER is used - * (if defined) - * b) RTEMS_BSP_NETWORK_DRIVER_NAME/ - * RTEMS_BSP_NETWORK_DRIVER_ATTACH - * are tried - * MEMORY_CUSTOM Allocate the defined amount of - * memory for mbufs and mbuf clusters, - * respectively. Define to a comma ',' - * separated pair of two numerical - * values, e.g: 100*1024,200*1024 - * MEMORY_SCARCE Allocate few memory for mbufs - * (hint for how much memory the - * board has) - * MEMORY_HUGE Allocate a lot of memory for mbufs - * (hint for how much memory the - * board has) - * If none of MEMORY_CUSTOM/ - * MEMORY_SCARCE/MEMORY_HUGE are - * defined then a medium amount of - * memory is allocated for mbufs. - */ - -#include -#include -#include - -#if 0 -#ifdef HAVE_CONFIG_H -#include -#else -#include "verscheck.h" -#endif -#endif - -//#define MULTI_NETDRIVER -//#define RTEMS_BSP_NETWORK_DRIVER_NAME 1 - -#define FIXED_IP_ADDR "192.168.1.249" -#define FIXED_NETMASK "255.255.255.0" - -#ifndef NETWORK_TASK_PRIORITY -#define NETWORK_TASK_PRIORITY 150 /* within EPICS' range */ -#endif - -/* make publicily available for startup scripts... */ -const int gesysNetworkTaskPriority = NETWORK_TASK_PRIORITY; - -#ifdef FIXED_IP_ADDR -#define RTEMS_DO_BOOTP 0 -#else -#define RTEMS_DO_BOOTP rtems_bsdnet_do_bootp -#define FIXED_IP_ADDR 0 -#undef FIXED_NETMASK -#define FIXED_NETMASK 0 -#endif - -#if !defined(NIC_NAME) - -#ifdef MULTI_NETDRIVER - -#if 0 -#if RTEMS_VERSION_ATLEAST(4,6,99) -#define pcib_init pci_initialize -#endif -#endif - -extern int rtems_3c509_driver_attach (struct rtems_bsdnet_ifconfig *, int); -extern int rtems_fxp_attach (struct rtems_bsdnet_ifconfig *, int); -extern int rtems_elnk_driver_attach (struct rtems_bsdnet_ifconfig *, int); -extern int rtems_dec21140_driver_attach (struct rtems_bsdnet_ifconfig *, int); - -/* these don't probe and will be used even if there's no device :-( */ -extern int rtems_ne_driver_attach (struct rtems_bsdnet_ifconfig *, int); -extern int rtems_wd_driver_attach (struct rtems_bsdnet_ifconfig *, int); - -static struct rtems_bsdnet_ifconfig isa_netdriver_config[] = { - { - "ep0", rtems_3c509_driver_attach, isa_netdriver_config + 1, - }, - { - "ne1", rtems_ne_driver_attach, 0, irno: 9 /* qemu cannot configure irq-no :-(; has it hardwired to 9 */ - }, -}; - -static struct rtems_bsdnet_ifconfig pci_netdriver_config[]= { - { - "dc1", rtems_dec21140_driver_attach, pci_netdriver_config+1, - }, -#if !defined(USE_LIBBSDPORT) - { - "fxp1", rtems_fxp_attach, pci_netdriver_config+2, - }, -#else - { - "", libbsdport_netdriver_attach, pci_netdriver_config+2, - }, -#endif - { - "elnk1", rtems_elnk_driver_attach, isa_netdriver_config, - }, -}; - -static int pci_check(struct rtems_bsdnet_ifconfig *ocfg, int attaching) -{ - struct rtems_bsdnet_ifconfig *cfg; - int if_index_pre; - extern int if_index; - if ( attaching ) { - cfg = pci_initialize() ? - isa_netdriver_config : pci_netdriver_config; - } - while ( cfg ) { - printk("Probing '%s'", cfg->name); - /* unfortunately, the return value is unreliable - some drivers report - * success even if they fail. - * Check if they chained an interface (ifnet) structure instead - */ - if_index_pre = if_index; - cfg->attach(cfg, attaching); - if ( if_index > if_index_pre ) { - /* assume success */ - printk(" .. seemed to work\n"); - ocfg->name = cfg->name; - ocfg->attach = cfg->attach; - return 0; - } - printk(" .. failed\n"); - cfg = cfg->next; - } - return -1; -} - - -#define NIC_NAME "dummy" -#define NIC_ATTACH pci_check - -#else - -#if defined(RTEMS_BSP_NETWORK_DRIVER_NAME) /* Use NIC provided by BSP */ - -/* force ne2k_isa on i386 for qemu */ -#if defined(__i386__) -# define NIC_NAME BSP_NE2000_NETWORK_DRIVER_NAME -# define NIC_ATTACH BSP_NE2000_NETWORK_DRIVER_ATTACH - -#else - -# define NIC_NAME RTEMS_BSP_NETWORK_DRIVER_NAME -# define NIC_ATTACH RTEMS_BSP_NETWORK_DRIVER_ATTACH -#endif - -#endif - -#endif /* ifdef MULTI_NETDRIVER */ -#endif - - -#ifdef NIC_NAME - -extern int NIC_ATTACH(); - -#if RTEMS_BSP_NETWORK_DRIVER_ATTACH == BSP_NE2000_NETWORK_DRIVER_ATTACH -static char ethernet_address[6] = { 0x00, 0xab, 0xcd, 0xef, 0x12, 0x34 }; -#endif - -static struct rtems_bsdnet_ifconfig netdriver_config[1] = {{ - NIC_NAME, /* name */ - (int (*)(struct rtems_bsdnet_ifconfig*,int))NIC_ATTACH, /* attach function */ - 0, /* link to next interface */ - FIXED_IP_ADDR, - FIXED_NETMASK -#if RTEMS_BSP_NETWORK_DRIVER_ATTACH == BSP_NE2000_NETWORK_DRIVER_ATTACH - , - ethernet_address, - irno:9, - port:0xc100 -#endif - } -}; -#else -#warning "NO KNOWN NETWORK DRIVER FOR THIS BSP -- YOU MAY HAVE TO EDIT networkconfig.h" -#endif - -struct rtems_bsdnet_config rtems_bsdnet_config = { -#ifdef NIC_NAME - netdriver_config, /* link to next interface */ - RTEMS_DO_BOOTP, /* Use BOOTP to get network configuration */ -#else - 0, - 0, -#endif - NETWORK_TASK_PRIORITY, /* Network task priority */ -#if defined(MEMORY_CUSTOM) - MEMORY_CUSTOM, -#elif defined(MEMORY_SCARCE) - 100*1024, /* MBUF space */ - 200*1024, /* MBUF cluster space */ -#elif defined(MEMORY_HUGE) - 2*1024*1024, /* MBUF space */ - 5*1024*1024, /* MBUF cluster space */ -#else - 180*1024, /* MBUF space */ - 350*1024, /* MBUF cluster space */ -#endif -#if (!defined (RTEMS_USE_BOOTP)) && defined(ON_RTEMS_LAB_WINSYSTEMS) - "rtems", /* Host name */ - "nodomain.com", /* Domain name */ - "192.168.1.14", /* Gateway */ - "192.168.1.1", /* Log host */ - {"89.212.75.6" }, /* Name server(s) */ - {"192.168.1.1" }, /* NTP server(s) */ -#else - NULL, /* Host name */ - NULL, /* Domain name */ - NULL, /* Gateway */ - NULL, /* Log host */ - { NULL }, /* Name server(s) */ - { NULL }, /* NTP server(s) */ -#endif /* !RTEMS_USE_BOOTP */ - 0, /* efficiency */ - 0, /* udp TX buffer */ - 0, /* udp RX buffer */ - 0, /* tcp TX buffer */ - 0, /* tcp RX buffer */ -}; -#endif /* _RTEMS_NETWORKCONFIG_H_ */ From 4fcbdff5800a3389e0ac78828911bff33a62cf0e Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Mon, 19 Mar 2018 15:36:21 -0700 Subject: [PATCH 2/7] missing includes --- examples/putme.cpp | 1 + src/client/client.cpp | 1 + src/client/clientSync.cpp | 1 + 3 files changed, 3 insertions(+) diff --git a/examples/putme.cpp b/examples/putme.cpp index 97bdc73..52c8e72 100644 --- a/examples/putme.cpp +++ b/examples/putme.cpp @@ -25,6 +25,7 @@ #include #include //! [Headers] +#include namespace pvd = epics::pvData; namespace pva = epics::pvAccess; diff --git a/src/client/client.cpp b/src/client/client.cpp index 2966e3c..e797f1d 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #define epicsExportSharedSymbols #include "pv/logger.h" diff --git a/src/client/clientSync.cpp b/src/client/clientSync.cpp index 8bc3fea..115c70a 100644 --- a/src/client/clientSync.cpp +++ b/src/client/clientSync.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #define epicsExportSharedSymbols #include "pv/logger.h" From e9cc8298a6b4bb3617db2aae7d1dc986c0627e6d Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 22 Mar 2018 13:34:55 -0700 Subject: [PATCH 3/7] server monitor cleanup ServerMonitorRequesterImpl::getChannelMonitor() seems like no possibility of deadlock atm. --- src/server/responseHandlers.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/server/responseHandlers.cpp b/src/server/responseHandlers.cpp index 8267292..bd86012 100644 --- a/src/server/responseHandlers.cpp +++ b/src/server/responseHandlers.cpp @@ -1985,7 +1985,7 @@ void ServerMonitorRequesterImpl::monitorConnect(const Status& status, Monitor::s { Lock guard(_mutex); _status = status; - _channelMonitor = monitor; //TODO inconsistent locking for _channelMonitor + _channelMonitor = monitor; _structure = structure; } TransportSender::shared_pointer thisSender = shared_from_this(); @@ -2053,7 +2053,7 @@ void ServerMonitorRequesterImpl::destroy() Monitor::shared_pointer ServerMonitorRequesterImpl::getChannelMonitor() { - //Lock guard(_mutex); + Lock guard(_mutex); return _channelMonitor; } @@ -2082,14 +2082,14 @@ void ServerMonitorRequesterImpl::send(ByteBuffer* buffer, TransportSendControl* } else { - Monitor::shared_pointer monitor = _channelMonitor; + Monitor::shared_pointer monitor(_channelMonitor); if (!monitor) return; // TODO asCheck ? - MonitorElement::shared_pointer element = monitor->poll(); - if (element.get()) + MonitorElement::Ref element(monitor); + if (element) { control->startMessage((int8)CMD_MONITOR, sizeof(int32)/sizeof(int8) + 1); buffer->putInt(_ioid); @@ -2106,7 +2106,7 @@ void ServerMonitorRequesterImpl::send(ByteBuffer* buffer, TransportSendControl* element->overrunBitSet->serialize(buffer, control); } - monitor->release(element); + element.reset(); // TODO if we try to proces several monitors at once, then fairness suffers // TODO compbine several monitors into one message (reduces payload) From 3b53e81f2f2f0ae1bc6d953856703b6e19c796b3 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 22 Mar 2018 13:39:04 -0700 Subject: [PATCH 4/7] avoid destroy() w/ lock --- src/server/responseHandlers.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/server/responseHandlers.cpp b/src/server/responseHandlers.cpp index bd86012..3251179 100644 --- a/src/server/responseHandlers.cpp +++ b/src/server/responseHandlers.cpp @@ -2043,12 +2043,13 @@ void ServerMonitorRequesterImpl::destroy() // asCheck _channel->getChannelSecuritySession()->release(_ioid); - if (_channelMonitor) - { - _channelMonitor->destroy(); + if (_channelMonitor) { _channelMonitor.reset(); } } + if(monitor) { + monitor->destroy(); + } } Monitor::shared_pointer ServerMonitorRequesterImpl::getChannelMonitor() From 8d363f9fe745e9e387844d7db17c277029eab155 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 22 Mar 2018 14:03:57 -0700 Subject: [PATCH 5/7] server responseHandlers annotate OVERRIDE FINAL --- src/server/pv/baseChannelRequester.h | 8 +- src/server/pv/responseHandlers.h | 180 ++++++++++++++------------- 2 files changed, 99 insertions(+), 89 deletions(-) diff --git a/src/server/pv/baseChannelRequester.h b/src/server/pv/baseChannelRequester.h index d4ac4da..60a3ba0 100644 --- a/src/server/pv/baseChannelRequester.h +++ b/src/server/pv/baseChannelRequester.h @@ -27,8 +27,8 @@ public: bool startRequest(epics::pvData::int32 qos); void stopRequest(); epics::pvData::int32 getPendingRequest(); - std::string getRequesterName(); - void message(std::string const & message, epics::pvData::MessageType messageType); + std::string getRequesterName() OVERRIDE FINAL; + virtual void message(std::string const & message, epics::pvData::MessageType messageType) OVERRIDE FINAL; static void message(Transport::shared_pointer const & transport, const pvAccessID ioid, const std::string message, const epics::pvData::MessageType messageType); static void sendFailureMessage(const epics::pvData::int8 command, Transport::shared_pointer const & transport, const pvAccessID ioid, const epics::pvData::int8 qos, const epics::pvData::Status status); @@ -55,7 +55,7 @@ class BaseChannelRequesterMessageTransportSender : public TransportSender { public: BaseChannelRequesterMessageTransportSender(const pvAccessID _ioid, const std::string message,const epics::pvData::MessageType messageType); - void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control); + virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL; private: const pvAccessID _ioid; const std::string _message; @@ -66,7 +66,7 @@ class BaseChannelRequesterFailureMessageTransportSender : public TransportSender { public: BaseChannelRequesterFailureMessageTransportSender(const epics::pvData::int8 command, Transport::shared_pointer const & transport, const pvAccessID ioid, const epics::pvData::int8 qos, const epics::pvData::Status& status); - void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control); + virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL; private: const epics::pvData::int8 _command; diff --git a/src/server/pv/responseHandlers.h b/src/server/pv/responseHandlers.h index 78f96a2..c391c28 100644 --- a/src/server/pv/responseHandlers.h +++ b/src/server/pv/responseHandlers.h @@ -28,8 +28,7 @@ public: ResponseHandler(context.get(), description), _context(context) { } - virtual ~AbstractServerResponseHandler() { - } + virtual ~AbstractServerResponseHandler() {} }; /** @@ -46,7 +45,7 @@ public: virtual void handleResponse(osiSockAddr* responseFrom, Transport::shared_pointer const & transport, epics::pvData::int8 version, epics::pvData::int8 command, - std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer); + std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer) OVERRIDE FINAL; }; /** @@ -61,7 +60,7 @@ public: virtual void handleResponse(osiSockAddr* responseFrom, Transport::shared_pointer const & transport, epics::pvData::int8 version, epics::pvData::int8 command, - std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer); + std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer) OVERRIDE FINAL; }; /** @@ -87,7 +86,7 @@ public: virtual void handleResponse(osiSockAddr* responseFrom, Transport::shared_pointer const & transport, epics::pvData::int8 version, epics::pvData::int8 command, - std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer); + std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer) OVERRIDE FINAL; }; class EchoTransportSender : public TransportSender { @@ -96,10 +95,9 @@ public: memcpy(&_echoFrom, echoFrom, sizeof(osiSockAddr)); } - virtual ~EchoTransportSender() { - } + virtual ~EchoTransportSender() {} - virtual void send(epics::pvData::ByteBuffer* /*buffer*/, TransportSendControl* control) { + virtual void send(epics::pvData::ByteBuffer* /*buffer*/, TransportSendControl* control) OVERRIDE FINAL { control->startMessage(CMD_ECHO, 0); control->setRecipient(_echoFrom); // TODO content @@ -127,7 +125,7 @@ public: virtual void handleResponse(osiSockAddr* responseFrom, Transport::shared_pointer const & transport, epics::pvData::int8 version, epics::pvData::int8 command, - std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer); + std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer) OVERRIDE FINAL; private: std::vector _providers; @@ -146,12 +144,12 @@ public: void clear(); ServerChannelFindRequesterImpl* set(std::string _name, epics::pvData::int32 searchSequenceId, epics::pvData::int32 cid, osiSockAddr const & sendTo, bool responseRequired, bool serverSearch); - void channelFindResult(const epics::pvData::Status& status, ChannelFind::shared_pointer const & channelFind, bool wasFound); + virtual void channelFindResult(const epics::pvData::Status& status, ChannelFind::shared_pointer const & channelFind, bool wasFound) OVERRIDE FINAL; - void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control); + virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL; - void callback(); - void timerStopped(); + virtual void callback() OVERRIDE FINAL; + virtual void timerStopped() OVERRIDE FINAL; private: ServerGUID _guid; @@ -183,7 +181,7 @@ public: virtual void handleResponse(osiSockAddr* responseFrom, Transport::shared_pointer const & transport, epics::pvData::int8 version, epics::pvData::int8 command, - std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer); + std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer) OVERRIDE FINAL; private: static std::string SERVER_CHANNEL_NAME; @@ -214,11 +212,11 @@ public: static ChannelRequester::shared_pointer create(ChannelProvider::shared_pointer const & provider, Transport::shared_pointer const & transport, const std::string channelName, const pvAccessID cid, ChannelSecuritySession::shared_pointer const & css); - void channelCreated(const epics::pvData::Status& status, Channel::shared_pointer const & channel); - void channelStateChange(Channel::shared_pointer const & c, const Channel::ConnectionState isConnected); - std::string getRequesterName(); - void message(std::string const & message, epics::pvData::MessageType messageType); - void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control); + virtual void channelCreated(const epics::pvData::Status& status, Channel::shared_pointer const & channel) OVERRIDE FINAL; + virtual void channelStateChange(Channel::shared_pointer const & c, const Channel::ConnectionState isConnected) OVERRIDE FINAL; + virtual std::string getRequesterName() OVERRIDE FINAL; + virtual void message(std::string const & message, epics::pvData::MessageType messageType) OVERRIDE FINAL; + virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL; private: ServerChannel::weak_pointer _serverChannel; std::tr1::weak_ptr _transport; @@ -243,7 +241,7 @@ public: virtual void handleResponse(osiSockAddr* responseFrom, Transport::shared_pointer const & transport, epics::pvData::int8 version, epics::pvData::int8 command, - std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer); + std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer) OVERRIDE FINAL; }; @@ -254,7 +252,7 @@ public: } virtual ~ServerDestroyChannelHandlerTransportSender() {} - void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) { + virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL { control->startMessage((epics::pvData::int8)CMD_DESTROY_CHANNEL, 2*sizeof(epics::pvData::int32)/sizeof(epics::pvData::int8)); buffer->putInt(_sid); buffer->putInt(_cid); @@ -279,7 +277,7 @@ public: virtual void handleResponse(osiSockAddr* responseFrom, Transport::shared_pointer const & transport, epics::pvData::int8 version, epics::pvData::int8 command, - std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer); + std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer) OVERRIDE FINAL; }; class ServerChannelGetRequesterImpl : @@ -302,16 +300,16 @@ public: Transport::shared_pointer const & transport, epics::pvData::PVStructure::shared_pointer const & pvRequest); virtual ~ServerChannelGetRequesterImpl() {} - void channelGetConnect(const epics::pvData::Status& status, ChannelGet::shared_pointer const & channelGet, - epics::pvData::Structure::const_shared_pointer const & structure); - void getDone(const epics::pvData::Status& status, ChannelGet::shared_pointer const & channelGet, - epics::pvData::PVStructure::shared_pointer const & pvStructure, - epics::pvData::BitSet::shared_pointer const & bitSet); - void destroy(); + virtual void channelGetConnect(const epics::pvData::Status& status, ChannelGet::shared_pointer const & channelGet, + epics::pvData::Structure::const_shared_pointer const & structure) OVERRIDE FINAL; + virtual void getDone(const epics::pvData::Status& status, ChannelGet::shared_pointer const & channelGet, + epics::pvData::PVStructure::shared_pointer const & pvStructure, + epics::pvData::BitSet::shared_pointer const & bitSet) OVERRIDE FINAL; + virtual void destroy() OVERRIDE FINAL; ChannelGet::shared_pointer getChannelGet(); - void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control); + virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL; private: // Note: this forms a reference loop, which is broken in destroy() ChannelGet::shared_pointer _channelGet; @@ -335,7 +333,7 @@ public: virtual void handleResponse(osiSockAddr* responseFrom, Transport::shared_pointer const & transport, epics::pvData::int8 version, epics::pvData::int8 command, - std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer); + std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer) OVERRIDE FINAL; }; class ServerChannelPutRequesterImpl : @@ -358,10 +356,13 @@ public: Transport::shared_pointer const & transport,epics::pvData::PVStructure::shared_pointer const & pvRequest); virtual ~ServerChannelPutRequesterImpl() {} - void channelPutConnect(const epics::pvData::Status& status, ChannelPut::shared_pointer const & channelPut, epics::pvData::Structure::const_shared_pointer const & structure); - void putDone(const epics::pvData::Status& status, ChannelPut::shared_pointer const & channelPut); - void getDone(const epics::pvData::Status& status, ChannelPut::shared_pointer const & channelPut, epics::pvData::PVStructure::shared_pointer const & pvStructure, epics::pvData::BitSet::shared_pointer const & bitSet); - void destroy(); + virtual void channelPutConnect(const epics::pvData::Status& status, ChannelPut::shared_pointer const & channelPut, + epics::pvData::Structure::const_shared_pointer const & structure) OVERRIDE FINAL; + virtual void putDone(const epics::pvData::Status& status, ChannelPut::shared_pointer const & channelPut) OVERRIDE FINAL; + virtual void getDone(const epics::pvData::Status& status, ChannelPut::shared_pointer const & channelPut, + epics::pvData::PVStructure::shared_pointer const & pvStructure, + epics::pvData::BitSet::shared_pointer const & bitSet) OVERRIDE FINAL; + virtual void destroy() OVERRIDE FINAL; ChannelPut::shared_pointer getChannelPut(); epics::pvData::BitSet::shared_pointer getPutBitSet(); @@ -389,7 +390,7 @@ public: virtual ~ServerPutGetHandler() {} virtual void handleResponse(osiSockAddr* responseFrom, Transport::shared_pointer const & transport, epics::pvData::int8 version, epics::pvData::int8 command, - std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer); + std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer) OVERRIDE FINAL; }; class ServerChannelPutGetRequesterImpl : @@ -412,26 +413,26 @@ public: Transport::shared_pointer const & transport,epics::pvData::PVStructure::shared_pointer const & pvRequest); virtual ~ServerChannelPutGetRequesterImpl() {} - void channelPutGetConnect(const epics::pvData::Status& status, ChannelPutGet::shared_pointer const & channelPutGet, - epics::pvData::Structure::const_shared_pointer const & putStructure, - epics::pvData::Structure::const_shared_pointer const & getStructure); - void getGetDone(const epics::pvData::Status& status, ChannelPutGet::shared_pointer const & channelPutGet, - epics::pvData::PVStructure::shared_pointer const & pvStructure, - epics::pvData::BitSet::shared_pointer const & bitSet); - void getPutDone(const epics::pvData::Status& status, ChannelPutGet::shared_pointer const & channelPutGet, - epics::pvData::PVStructure::shared_pointer const & pvStructure, - epics::pvData::BitSet::shared_pointer const & bitSet); - void putGetDone(const epics::pvData::Status& status, ChannelPutGet::shared_pointer const & channelPutGet, - epics::pvData::PVStructure::shared_pointer const & pvStructure, - epics::pvData::BitSet::shared_pointer const & bitSet); - void destroy(); + virtual void channelPutGetConnect(const epics::pvData::Status& status, ChannelPutGet::shared_pointer const & channelPutGet, + epics::pvData::Structure::const_shared_pointer const & putStructure, + epics::pvData::Structure::const_shared_pointer const & getStructure) OVERRIDE FINAL; + virtual void getGetDone(const epics::pvData::Status& status, ChannelPutGet::shared_pointer const & channelPutGet, + epics::pvData::PVStructure::shared_pointer const & pvStructure, + epics::pvData::BitSet::shared_pointer const & bitSet) OVERRIDE FINAL; + virtual void getPutDone(const epics::pvData::Status& status, ChannelPutGet::shared_pointer const & channelPutGet, + epics::pvData::PVStructure::shared_pointer const & pvStructure, + epics::pvData::BitSet::shared_pointer const & bitSet) OVERRIDE FINAL; + virtual void putGetDone(const epics::pvData::Status& status, ChannelPutGet::shared_pointer const & channelPutGet, + epics::pvData::PVStructure::shared_pointer const & pvStructure, + epics::pvData::BitSet::shared_pointer const & bitSet) OVERRIDE FINAL; + virtual void destroy() OVERRIDE FINAL; ChannelPutGet::shared_pointer getChannelPutGet(); epics::pvData::PVStructure::shared_pointer getPutGetPVStructure(); epics::pvData::BitSet::shared_pointer getPutGetBitSet(); - void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control); + virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL; private: // Note: this forms a reference loop, which is broken in destroy() ChannelPutGet::shared_pointer _channelPutGet; @@ -457,7 +458,7 @@ public: virtual void handleResponse(osiSockAddr* responseFrom, Transport::shared_pointer const & transport, epics::pvData::int8 version, epics::pvData::int8 command, - std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer); + std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer) OVERRIDE FINAL; }; @@ -481,13 +482,15 @@ public: Transport::shared_pointer const & transport,epics::pvData::PVStructure::shared_pointer const & pvRequest); virtual ~ServerMonitorRequesterImpl() {} - void monitorConnect(const epics::pvData::Status& status, Monitor::shared_pointer const & monitor, epics::pvData::StructureConstPtr const & structure); - void unlisten(Monitor::shared_pointer const & monitor); - void monitorEvent(Monitor::shared_pointer const & monitor); - void destroy(); + virtual void monitorConnect(const epics::pvData::Status& status, + Monitor::shared_pointer const & monitor, + epics::pvData::StructureConstPtr const & structure) OVERRIDE FINAL; + virtual void unlisten(Monitor::shared_pointer const & monitor) OVERRIDE FINAL; + virtual void monitorEvent(Monitor::shared_pointer const & monitor) OVERRIDE FINAL; + virtual void destroy() OVERRIDE FINAL; Monitor::shared_pointer getChannelMonitor(); - void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control); + virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL; private: // Note: this forms a reference loop, which is broken in destroy() Monitor::shared_pointer _channelMonitor; @@ -511,7 +514,7 @@ public: virtual void handleResponse(osiSockAddr* responseFrom, Transport::shared_pointer const & transport, epics::pvData::int8 version, epics::pvData::int8 command, - std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer); + std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer) OVERRIDE FINAL; }; class ServerChannelArrayRequesterImpl : @@ -534,19 +537,25 @@ public: Transport::shared_pointer const & transport,epics::pvData::PVStructure::shared_pointer const & pvRequest); virtual ~ServerChannelArrayRequesterImpl() {} - void channelArrayConnect(const epics::pvData::Status& status, ChannelArray::shared_pointer const & channelArray, epics::pvData::Array::const_shared_pointer const & array); - void getArrayDone(const epics::pvData::Status& status, ChannelArray::shared_pointer const & channelArray, - epics::pvData::PVArray::shared_pointer const & pvArray); - void putArrayDone(const epics::pvData::Status& status, ChannelArray::shared_pointer const & channelArray); - void setLengthDone(const epics::pvData::Status& status, ChannelArray::shared_pointer const & channelArray); - void getLengthDone(const epics::pvData::Status& status, ChannelArray::shared_pointer const & channelArray, - std::size_t length); - void destroy(); + virtual void channelArrayConnect(const epics::pvData::Status& status, + ChannelArray::shared_pointer const & channelArray, + epics::pvData::Array::const_shared_pointer const & array) OVERRIDE FINAL; + virtual void getArrayDone(const epics::pvData::Status& status, + ChannelArray::shared_pointer const & channelArray, + epics::pvData::PVArray::shared_pointer const & pvArray) OVERRIDE FINAL; + virtual void putArrayDone(const epics::pvData::Status& status, + ChannelArray::shared_pointer const & channelArray) OVERRIDE FINAL; + virtual void setLengthDone(const epics::pvData::Status& status, + ChannelArray::shared_pointer const & channelArray) OVERRIDE FINAL; + virtual void getLengthDone(const epics::pvData::Status& status, + ChannelArray::shared_pointer const & channelArray, + std::size_t length) OVERRIDE FINAL; + virtual void destroy() OVERRIDE FINAL; ChannelArray::shared_pointer getChannelArray(); epics::pvData::PVArray::shared_pointer getPVArray(); - void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control); + virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL; private: // Note: this forms a reference loop, which is broken in destroy() @@ -571,7 +580,7 @@ public: virtual void handleResponse(osiSockAddr* responseFrom, Transport::shared_pointer const & transport, epics::pvData::int8 version, epics::pvData::int8 command, - std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer); + std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer) OVERRIDE FINAL; private: void failureResponse(Transport::shared_pointer const & transport, pvAccessID ioid, const epics::pvData::Status& errorStatus); @@ -592,7 +601,7 @@ public: virtual void handleResponse(osiSockAddr* responseFrom, Transport::shared_pointer const & transport, epics::pvData::int8 version, epics::pvData::int8 command, - std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer); + std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer) OVERRIDE FINAL; private: void failureResponse(Transport::shared_pointer const & transport, pvAccessID ioid, const epics::pvData::Status& errorStatus); @@ -613,7 +622,7 @@ public: virtual void handleResponse(osiSockAddr* responseFrom, Transport::shared_pointer const & transport, epics::pvData::int8 version, epics::pvData::int8 command, - std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer); + std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer) OVERRIDE FINAL; }; class ServerChannelProcessRequesterImpl : @@ -636,12 +645,12 @@ public: Transport::shared_pointer const & transport, epics::pvData::PVStructure::shared_pointer const & pvRequest); virtual ~ServerChannelProcessRequesterImpl() {} - void channelProcessConnect(const epics::pvData::Status& status, ChannelProcess::shared_pointer const & channelProcess); - void processDone(const epics::pvData::Status& status, ChannelProcess::shared_pointer const & channelProcess); - void destroy(); + virtual void channelProcessConnect(const epics::pvData::Status& status, ChannelProcess::shared_pointer const & channelProcess) OVERRIDE FINAL; + virtual void processDone(const epics::pvData::Status& status, ChannelProcess::shared_pointer const & channelProcess) OVERRIDE FINAL; + virtual void destroy() OVERRIDE FINAL; ChannelProcess::shared_pointer getChannelProcess(); - void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control); + virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL; private: // Note: this forms a reference loop, which is broken in destroy() @@ -663,7 +672,7 @@ public: virtual void handleResponse(osiSockAddr* responseFrom, Transport::shared_pointer const & transport, epics::pvData::int8 version, epics::pvData::int8 command, - std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer); + std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer) OVERRIDE FINAL; private: void getFieldFailureResponse(Transport::shared_pointer const & transport, const pvAccessID ioid, const epics::pvData::Status& errorStatus); }; @@ -683,9 +692,9 @@ public: Transport::shared_pointer const & transport); virtual ~ServerGetFieldRequesterImpl() {} - void getDone(const epics::pvData::Status& status, epics::pvData::FieldConstPtr const & field); - void destroy(); - void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control); + virtual void getDone(const epics::pvData::Status& status, epics::pvData::FieldConstPtr const & field) OVERRIDE FINAL; + virtual void destroy() OVERRIDE FINAL; + virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL; private: bool done; epics::pvData::Status _status; @@ -701,7 +710,7 @@ public: } virtual ~ServerGetFieldHandlerTransportSender() {} - void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) { + virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL { control->startMessage((epics::pvData::int8)CMD_GET_FIELD, sizeof(epics::pvData::int32)/sizeof(epics::pvData::int8)); buffer->putInt(_ioid); _status.serialize(buffer, control); @@ -728,7 +737,7 @@ public: virtual void handleResponse(osiSockAddr* responseFrom, Transport::shared_pointer const & transport, epics::pvData::int8 version, epics::pvData::int8 command, - std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer); + std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer) OVERRIDE FINAL; }; class ServerChannelRPCRequesterImpl : @@ -751,15 +760,17 @@ public: Transport::shared_pointer const & transport,epics::pvData::PVStructure::shared_pointer const & pvRequest); virtual ~ServerChannelRPCRequesterImpl() {} - void channelRPCConnect(const epics::pvData::Status& status, ChannelRPC::shared_pointer const & channelRPC); - void requestDone(const epics::pvData::Status& status, ChannelRPC::shared_pointer const & channelRPC, epics::pvData::PVStructure::shared_pointer const & pvResponse); - void destroy(); + virtual void channelRPCConnect(const epics::pvData::Status& status, ChannelRPC::shared_pointer const & channelRPC) OVERRIDE FINAL; + virtual void requestDone(const epics::pvData::Status& status, + ChannelRPC::shared_pointer const & channelRPC, + epics::pvData::PVStructure::shared_pointer const & pvResponse) OVERRIDE FINAL; + virtual void destroy() OVERRIDE FINAL; /** * @return the channelRPC */ ChannelRPC::shared_pointer getChannelRPC(); - void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control); + virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL; private: // Note: this forms a reference loop, which is broken in destroy() ChannelRPC::shared_pointer _channelRPC; @@ -775,12 +786,11 @@ class ServerResponseHandler : public ResponseHandler { public: ServerResponseHandler(ServerContextImpl::shared_pointer const & context); - virtual ~ServerResponseHandler() { - } + virtual ~ServerResponseHandler() {} virtual void handleResponse(osiSockAddr* responseFrom, Transport::shared_pointer const & transport, epics::pvData::int8 version, epics::pvData::int8 command, - std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer); + std::size_t payloadSize, epics::pvData::ByteBuffer* payloadBuffer) OVERRIDE FINAL; private: ServerBadResponse handle_bad; From aec1c7c9d7a0ab0f4ae913de2962c9d824ebc367 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 28 Mar 2018 11:25:54 -0700 Subject: [PATCH 6/7] client search: cleanup context pointer handling --- src/remote/simpleChannelSearchManagerImpl.cpp | 18 +++++++++--------- src/remoteClient/clientContextImpl.cpp | 5 ++++- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/remote/simpleChannelSearchManagerImpl.cpp b/src/remote/simpleChannelSearchManagerImpl.cpp index 4f4a771..587859e 100644 --- a/src/remote/simpleChannelSearchManagerImpl.cpp +++ b/src/remote/simpleChannelSearchManagerImpl.cpp @@ -15,6 +15,7 @@ #include #include #include +#include using namespace std; using namespace epics::pvData; @@ -75,18 +76,17 @@ void SimpleChannelSearchManagerImpl::activate() // add some jitter so that all the clients do not send at the same time double period = ATOMIC_PERIOD + (rand() % (2*PERIOD_JITTER_MS+1) - PERIOD_JITTER_MS)/(double)1000; - Context::shared_pointer context = m_context.lock(); - if (context.get()) + Context::shared_pointer context(m_context.lock()); + if (context) context->getTimer()->schedulePeriodic(shared_from_this(), period, period); - - //new Thread(this, "pvAccess immediate-search").start(); } SimpleChannelSearchManagerImpl::~SimpleChannelSearchManagerImpl() { - // shared_from_this() is not allowed from destructor - // be sure to call cancel() first - // cancel(); + Lock guard(m_mutex); + if (!m_canceled.get()) { + LOG(logLevelWarn, "Logic error: SimpleChannelSearchManagerImpl destroyed w/o cancel()"); + } } void SimpleChannelSearchManagerImpl::cancel() @@ -97,8 +97,8 @@ void SimpleChannelSearchManagerImpl::cancel() return; m_canceled.set(); - Context::shared_pointer context = m_context.lock(); - if (context.get()) + Context::shared_pointer context(m_context.lock()); + if (context) context->getTimer()->cancel(shared_from_this()); } diff --git a/src/remoteClient/clientContextImpl.cpp b/src/remoteClient/clientContextImpl.cpp index 18ce6b1..6fe604d 100644 --- a/src/remoteClient/clientContextImpl.cpp +++ b/src/remoteClient/clientContextImpl.cpp @@ -2586,7 +2586,10 @@ public: // reads CIDs // TODO optimize - std::tr1::shared_ptr csm = _context.lock()->getChannelSearchManager(); + ClientContextImpl::shared_pointer context(_context.lock()); + if(!context) + return; + std::tr1::shared_ptr csm = context->getChannelSearchManager(); int16 count = payloadBuffer->getShort(); for (int i = 0; i < count; i++) { From 1a100a095513e76945426d5781a7506ef5bac28f Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 28 Mar 2018 13:21:46 -0700 Subject: [PATCH 7/7] client fix init order leading to *NULL Avoid a race between the main thread alloc of SimpleChannelSearchManagerImpl the the UDP socket worker trying to use the same. Split allocation and initialization of search manager around socket creation and worker start. Also in-line initializeUDPTransport() to only call site. --- .../pv/simpleChannelSearchManagerImpl.h | 9 +-- src/remote/simpleChannelSearchManagerImpl.cpp | 20 ++----- src/remoteClient/clientContextImpl.cpp | 57 +++++++++---------- 3 files changed, 34 insertions(+), 52 deletions(-) diff --git a/src/remote/pv/simpleChannelSearchManagerImpl.h b/src/remote/pv/simpleChannelSearchManagerImpl.h index a8fc32b..6a54818 100644 --- a/src/remote/pv/simpleChannelSearchManagerImpl.h +++ b/src/remote/pv/simpleChannelSearchManagerImpl.h @@ -59,11 +59,6 @@ class SimpleChannelSearchManagerImpl : public: POINTER_DEFINITIONS(SimpleChannelSearchManagerImpl); - /** - * Constructor. - * @param context - */ - static shared_pointer create(Context::shared_pointer const & context); /** * Constructor. * @param context @@ -109,8 +104,6 @@ public: /// Timer stooped callback. void timerStopped(); -private: - /** * Private constructor. * @param context @@ -118,6 +111,8 @@ private: SimpleChannelSearchManagerImpl(Context::shared_pointer const & context); void activate(); +private: + bool generateSearchRequestMessage(SearchInstance::shared_pointer const & channel, bool allowNewFrame, bool flush); static bool generateSearchRequestMessage(SearchInstance::shared_pointer const & channel, diff --git a/src/remote/simpleChannelSearchManagerImpl.cpp b/src/remote/simpleChannelSearchManagerImpl.cpp index 587859e..638f3b4 100644 --- a/src/remote/simpleChannelSearchManagerImpl.cpp +++ b/src/remote/simpleChannelSearchManagerImpl.cpp @@ -41,17 +41,9 @@ const int SimpleChannelSearchManagerImpl::MAX_FRAMES_AT_ONCE = 10; const int SimpleChannelSearchManagerImpl::DELAY_BETWEEN_FRAMES_MS = 50; -SimpleChannelSearchManagerImpl::shared_pointer -SimpleChannelSearchManagerImpl::create(Context::shared_pointer const & context) -{ - SimpleChannelSearchManagerImpl::shared_pointer thisPtr(new SimpleChannelSearchManagerImpl(context)); - thisPtr->activate(); - return thisPtr; -} - SimpleChannelSearchManagerImpl::SimpleChannelSearchManagerImpl(Context::shared_pointer const & context) : m_context(context), - m_responseAddress(context->getSearchTransport()->getRemoteAddress()), + m_responseAddress(), // initialized in activate() m_canceled(), m_sequenceNumber(0), m_sendBuffer(MAX_UDP_UNFRAGMENTED_SEND), @@ -62,17 +54,17 @@ SimpleChannelSearchManagerImpl::SimpleChannelSearchManagerImpl(Context::shared_p m_userValueMutex(), m_mutex() { - - // initialize send buffer - initializeSendBuffer(); - - // initialize random seed with some random value srand ( time(NULL) ); } void SimpleChannelSearchManagerImpl::activate() { + m_responseAddress = Context::shared_pointer(m_context)->getSearchTransport()->getRemoteAddress(); + + // initialize send buffer + initializeSendBuffer(); + // add some jitter so that all the clients do not send at the same time double period = ATOMIC_PERIOD + (rand() % (2*PERIOD_JITTER_MS+1) - PERIOD_JITTER_MS)/(double)1000; diff --git a/src/remoteClient/clientContextImpl.cpp b/src/remoteClient/clientContextImpl.cpp index 6fe604d..473b12e 100644 --- a/src/remoteClient/clientContextImpl.cpp +++ b/src/remoteClient/clientContextImpl.cpp @@ -4145,54 +4145,49 @@ private: osiSockAttach(); m_timer.reset(new Timer("pvAccess-client timer", lowPriority)); - InternalClientContextImpl::shared_pointer thisPointer = internal_from_this(); + InternalClientContextImpl::shared_pointer thisPointer(internal_from_this()); // stores weak_ptr m_connector.reset(new BlockingTCPConnector(thisPointer, m_receiveBufferSize, m_connectionTimeout)); // stores many weak_ptr m_responseHandler.reset(new ClientResponseHandler(thisPointer)); + m_channelSearchManager.reset(new SimpleChannelSearchManagerImpl(thisPointer)); + // preinitialize security plugins SecurityPluginRegistry::instance(); // TODO put memory barrier here... (if not already called within a lock?) // setup UDP transport - initializeUDPTransport(); + { + + // query broadcast addresses of all IFs + SOCKET socket = epicsSocketCreate(AF_INET, SOCK_DGRAM, 0); + if (socket == INVALID_SOCKET) + { + throw std::logic_error("Failed to create a socket to introspect network interfaces."); + } + + IfaceNodeVector ifaceList; + if (discoverInterfaces(ifaceList, socket, 0) || ifaceList.size() == 0) + { + LOG(logLevelError, "Failed to introspect interfaces or no network interfaces available."); + } + epicsSocketDestroy (socket); + + initializeUDPTransports(false, m_udpTransports, ifaceList, m_responseHandler, m_searchTransport, + m_broadcastPort, m_autoAddressList, m_addressList, std::string()); + + } // setup search manager - m_channelSearchManager = SimpleChannelSearchManagerImpl::create(thisPointer); + // Starts timer + m_channelSearchManager->activate(); // TODO what if initialization failed!!! } - /** - * Initialized UDP transport (broadcast socket and repeater connection). - */ - bool initializeUDPTransport() { - - // query broadcast addresses of all IFs - SOCKET socket = epicsSocketCreate(AF_INET, SOCK_DGRAM, 0); - if (socket == INVALID_SOCKET) - { - LOG(logLevelError, "Failed to create a socket to introspect network interfaces."); - return false; - } - - IfaceNodeVector ifaceList; - if (discoverInterfaces(ifaceList, socket, 0) || ifaceList.size() == 0) - { - LOG(logLevelError, "Failed to introspect interfaces or no network interfaces available."); - return false; - } - epicsSocketDestroy (socket); - - initializeUDPTransports(false, m_udpTransports, ifaceList, m_responseHandler, m_searchTransport, - m_broadcastPort, m_autoAddressList, m_addressList, std::string()); - - return true; - } - void internalDestroy() { // @@ -4591,7 +4586,7 @@ private: * Channel search manager. * Manages UDP search requests. */ - ChannelSearchManager::shared_pointer m_channelSearchManager; + SimpleChannelSearchManagerImpl::shared_pointer m_channelSearchManager; /** * Beacon handler map.